diff --git a/docs/source/usage/python.rst b/docs/source/usage/python.rst index 52acfe210..948de5a6b 100644 --- a/docs/source/usage/python.rst +++ b/docs/source/usage/python.rst @@ -496,7 +496,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) +.. py:class:: impactx.elements.CFbend(ds, rc, k, dx=0, dy=0, rotation=0, nslice=1, name=None) A combined function bending magnet. This is an ideal Sbend with a normal quadrupole field component. @@ -510,8 +510,9 @@ 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 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) +.. py:class:: impactx.elements.ConstF(ds, kx, ky, kt, dx=0, dy=0, rotation=0, nslice=1, name=None) A linear Constant Focusing element. @@ -523,6 +524,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 nslice: number of slices used for the application of space charge + :param name: an optional name for the element .. py:property:: kx @@ -536,7 +538,7 @@ This module provides elements for the accelerator lattice. focusing t strength in 1/m -.. py:class:: impactx.elements.DipEdge(psi, rc, g, K2, dx=0, dy=0, rotation=0) +.. py:class:: impactx.elements.DipEdge(psi, rc, g, K2, dx=0, dy=0, rotation=0, name=None) Edge focusing associated with bend entry or exit @@ -555,15 +557,17 @@ 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 name: an optional name for the element -.. py:class:: impactx.elements.Drift(ds, dx=0, dy=0, rotation=0, nslice=1) +.. py:class:: impactx.elements.Drift(ds, dx=0, dy=0, rotation=0, nslice=1, name=None) A drift. :param ds: Segment length 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.ChrDrift(ds, dx=0, dy=0, rotation=0, nslice=1) +.. py:class:: impactx.elements.ChrDrift(ds, dx=0, dy=0, rotation=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 @@ -574,8 +578,9 @@ 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 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) +.. py:class:: impactx.elements.ExactDrift(ds, dx=0, dy=0, rotation=0, nslice=1, name=None) A drift using the exact nonlinear transfer map. @@ -584,16 +589,18 @@ 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 nslice: number of slices used for the application of space charge + :param name: an optional name for the element -.. py:class:: impactx.elements.Kicker(xkick, ykick, unit="dimensionless", dx=0, dy=0, rotation=0) +.. py:class:: impactx.elements.Kicker(xkick, ykick, unit="dimensionless", dx=0, dy=0, rotation=0, name=None) A thin transverse kicker. :param xkick: horizontal kick strength (dimensionless OR T-m) :param ykick: vertical kick strength (dimensionless OR T-m) :param unit: specification of units (``"dimensionless"`` in units of the magnetic rigidity of the reference particle or ``"T-m"``) + :param name: an optional name for the element -.. py:class:: impactx.elements.Multipole(multipole, K_normal, K_skew, dx=0, dy=0, rotation=0) +.. py:class:: impactx.elements.Multipole(multipole, K_normal, K_skew, dx=0, dy=0, rotation=0, name=None) A general thin multipole element. @@ -603,12 +610,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 name: an optional name for the element .. py::class:: impactx.elements.Empty This element does nothing. -.. py:class:: impactx.elements.NonlinearLens(knll, cnll, dx=0, dy=0, rotation=0) +.. py:class:: impactx.elements.NonlinearLens(knll, cnll, dx=0, dy=0, rotation=0, name=None) Single short segment of the nonlinear magnetic insert element. @@ -622,6 +630,7 @@ 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 name: an optional name for the element .. py:class:: impactx.elements.BeamMonitor(name, backend="default", encoding="g") @@ -667,7 +676,7 @@ This module provides elements for the accelerator lattice. Scale factor (in meters^(1/2)) of the IOTA nonlinear magnetic insert element used for computing H and I. -.. py:class:: impactx.elements.Programmable +.. py:class:: impactx.elements.Programmable(ds=0.0, nslice=1, name=None) A programmable beam optics element. @@ -675,6 +684,7 @@ This module provides elements for the accelerator lattice. :param ds: Segment length in m. :param nslice: number of slices used for the application of space charge + :param name: an optional name for the element .. py:property:: push @@ -707,7 +717,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) +.. py:class:: impactx.elements.Quad(ds, k, dx=0, dy=0, rotation=0, nslice=1, name=None) A Quadrupole magnet. @@ -720,8 +730,9 @@ 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 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) +.. py:class:: impactx.elements.ChrQuad(ds, k, unit=0, dx=0, dy=0, rotation=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 @@ -738,6 +749,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 nslice: number of slices used for the application of space charge + :param name: an optional name for the element .. py:property:: k @@ -747,7 +759,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) +.. py:class:: impactx.elements.ChrPlasmaLens(ds, k, unit=0, dx=0, dy=0, rotation=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 @@ -762,6 +774,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 nslice: number of slices used for the application of space charge + :param name: an optional name for the element .. py:property:: k @@ -771,7 +784,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) +.. py:class:: impactx.elements.ChrAcc(ds, ez, bz, dx=0, dy=0, rotation=0, nslice=1, name=None) Acceleration in a uniform field Ez, with a uniform solenoidal field Bz. @@ -787,6 +800,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 nslice: number of slices used for the application of space charge + :param name: an optional name for the element .. py:property:: ez @@ -796,7 +810,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) +.. 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) A radiofrequency cavity. @@ -813,8 +827,9 @@ This module provides elements for the accelerator lattice. :param rotation: rotation error in the transverse plane [degrees] :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) +.. py:class:: impactx.elements.Sbend(ds, rc, dx=0, dy=0, rotation=0, nslice=1, name=None) An ideal sector bend. @@ -824,8 +839,9 @@ 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 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) +.. py:class:: impactx.elements.ExactSbend(ds, phi, B=0.0, dx=0, dy=0, rotation=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. @@ -842,6 +858,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 nslice: number of slices used for the application of space charge + :param name: an optional name for the element .. py:class:: impactx.elements.Buncher(V, k, dx=0, dy=0, rotation=0) @@ -853,7 +870,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] -.. py:class:: impactx.elements.ShortRF(V, freq, phase=-90.0, dx=0, dy=0, rotation=0) +.. py:class:: impactx.elements.ShortRF(V, freq, phase=-90.0, dx=0, dy=0, rotation=0, name=None) A short RF cavity element (MAD-X model). @@ -863,8 +880,9 @@ 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 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) +.. 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) A soft-edge solenoid. @@ -882,8 +900,9 @@ This module provides elements for the accelerator lattice. :param rotation: rotation error in the transverse plane [degrees] :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) +.. py:class:: impactx.elements.Sol(ds, ks, dx=0, dy=0, rotation=0, nslice=1, name=None) An ideal hard-edge Solenoid magnet. @@ -893,15 +912,17 @@ 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 nslice: number of slices used for the application of space charge + :param name: an optional name for the element -.. py:class:: impactx.elements.PRot(phi_in, phi_out) +.. py:class:: impactx.elements.PRot(phi_in, phi_out, name=None) Exact map for a pole-face rotation in the x-z plane. :param phi_in: angle of the reference particle with respect to the longitudinal (z) axis in the original frame in degrees :param phi_out: angle of the reference particle with respect to the longitudinal (z) axis in the rotated frame in degrees + :param name: an optional name for the element -.. py:class:: impactx.elements.Aperture(xmax, ymax, shape="rectangular", dx=0, dy=0, rotation=0) +.. py:class:: impactx.elements.Aperture(xmax, ymax, shape="rectangular", dx=0, dy=0, rotation=0, name=None) A thin collimator element, applying a transverse aperture boundary. @@ -911,6 +932,7 @@ 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 name: an optional name for the element .. py:property:: shape @@ -924,7 +946,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) +.. py:class:: impactx.elements.SoftQuadrupole(ds, gscale, cos_coefficients, sin_coefficients, dx=0, dy=0, rotation=0, mapsteps=1, nslice=1, name=None) A soft-edge quadrupole. @@ -939,8 +961,9 @@ This module provides elements for the accelerator lattice. :param rotation: rotation error in the transverse plane [degrees] :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.ThinDipole(theta, rc, dx=0, dy=0, rotation=0) +.. py:class:: impactx.elements.ThinDipole(theta, rc, dx=0, dy=0, rotation=0, name=None) A general thin dipole element. @@ -949,12 +972,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 name: an optional name for the element Reference: * G. Ripken and F. Schmidt, Thin-Lens Formalism for Tracking, CERN/SL/95-12 (AP), 1995. -.. py:class:: impactx.elements.TaperedPL(k, taper, unit=0, dx=0, dy=0, rotation=0) +.. py:class:: impactx.elements.TaperedPL(k, taper, unit=0, dx=0, dy=0, rotation=0, name=None) A thin nonlinear plasma lens with transverse (horizontal) taper @@ -974,6 +998,7 @@ 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 name: an optional name for the element .. py:property:: k diff --git a/examples/achromatic_spectrometer/run_spectrometer.py b/examples/achromatic_spectrometer/run_spectrometer.py index 21346676e..3ea598645 100755 --- a/examples/achromatic_spectrometer/run_spectrometer.py +++ b/examples/achromatic_spectrometer/run_spectrometer.py @@ -58,17 +58,17 @@ # drifts appearing the drift-kick sequence ds_half = ds / 2.0 -dr = elements.Drift(ds=ds_half, nslice=ns) +dr = elements.Drift(name="dr", ds=ds_half, nslice=ns) # define the lens segments thick_lens = [] for _ in range(0, num_lenses): - pl = elements.TaperedPL(k=dk, taper=dtaper, unit=0) + pl = elements.TaperedPL(name="pl", k=dk, taper=dtaper, unit=0) segment = [dr, pl, dr] thick_lens.extend(segment) -bend = elements.ExactSbend(ds=1.0, phi=10.0, B=0.0, nslice=ns) -drift = elements.Drift(ds=1.0, nslice=ns) +bend = elements.ExactSbend(name="bend", ds=1.0, phi=10.0, B=0.0, nslice=ns) +drift = elements.Drift(name="drift", ds=1.0, nslice=ns) # specify the lattice sequence sim.lattice.append(monitor) diff --git a/examples/aperture/run_aperture.py b/examples/aperture/run_aperture.py index 7e8cc73fc..39ff1e6fa 100755 --- a/examples/aperture/run_aperture.py +++ b/examples/aperture/run_aperture.py @@ -54,8 +54,10 @@ sim.lattice.extend( [ monitor, - elements.Drift(0.123), - elements.Aperture(xmax=1.0e-3, ymax=1.5e-3, shape="rectangular"), + elements.Drift(name="drift", ds=0.123), + elements.Aperture( + name="collimator", xmax=1.0e-3, ymax=1.5e-3, shape="rectangular" + ), monitor, ] ) diff --git a/examples/apochromatic/run_apochromatic.py b/examples/apochromatic/run_apochromatic.py index b2333edcc..c25802ae3 100644 --- a/examples/apochromatic/run_apochromatic.py +++ b/examples/apochromatic/run_apochromatic.py @@ -50,18 +50,18 @@ ns = 25 # number of slices per ds in the element # Drift elements -dr1 = elements.ChrDrift(ds=1.0, nslice=ns) -dr2 = elements.ChrDrift(ds=10.0, nslice=ns) +dr1 = elements.ChrDrift(name="dr1", ds=1.0, nslice=ns) +dr2 = elements.ChrDrift(name="dr2", ds=10.0, nslice=ns) # Quad elements -q1 = elements.ChrQuad(ds=1.2258333333, k=0.5884, nslice=ns) -q2 = elements.ChrQuad(ds=1.5677083333, k=-0.7525, nslice=ns) -q3 = elements.ChrQuad(ds=1.205625, k=0.5787, nslice=ns) -q4 = elements.ChrQuad(ds=1.2502083333, k=-0.6001, nslice=ns) -q5 = elements.ChrQuad(ds=1.2502083333, k=0.6001, nslice=ns) -q6 = elements.ChrQuad(ds=1.205625, k=-0.5787, nslice=ns) -q7 = elements.ChrQuad(ds=1.5677083333, k=0.7525, nslice=ns) -q8 = elements.ChrQuad(ds=1.2258333333, k=-0.5884, nslice=ns) +q1 = elements.ChrQuad(name="q1", ds=1.2258333333, k=0.5884, nslice=ns) +q2 = elements.ChrQuad(name="q2", ds=1.5677083333, k=-0.7525, nslice=ns) +q3 = elements.ChrQuad(name="q3", ds=1.205625, k=0.5787, nslice=ns) +q4 = elements.ChrQuad(name="q4", ds=1.2502083333, k=-0.6001, nslice=ns) +q5 = elements.ChrQuad(name="q5", ds=1.2502083333, k=0.6001, nslice=ns) +q6 = elements.ChrQuad(name="q6", ds=1.205625, k=-0.5787, nslice=ns) +q7 = elements.ChrQuad(name="q7", ds=1.5677083333, k=0.7525, nslice=ns) +q8 = elements.ChrQuad(name="q8", ds=1.2258333333, k=-0.5884, nslice=ns) lattice_line = [monitor, dr1, q1, q2, q3, dr2, q4, q5, dr2, q6, q7, q8, dr1, monitor] diff --git a/examples/apochromatic/run_apochromatic_pl.py b/examples/apochromatic/run_apochromatic_pl.py index f31a4b401..af78089df 100644 --- a/examples/apochromatic/run_apochromatic_pl.py +++ b/examples/apochromatic/run_apochromatic_pl.py @@ -50,39 +50,39 @@ ns = 25 # number of slices per ds in the element # Drift elements -dr1 = elements.ChrDrift(ds=1.0, nslice=ns) -dr2 = elements.ChrDrift(ds=2.0, nslice=ns) +dr1 = elements.ChrDrift(name="dr1", ds=1.0, nslice=ns) +dr2 = elements.ChrDrift(name="dr2", ds=2.0, nslice=ns) # Plasma lens elements q1 = elements.ChrPlasmaLens( - ds=0.331817852986604588, k=996.147787384348956, unit=1, nslice=ns + name="q1", ds=0.331817852986604588, k=996.147787384348956, unit=1, nslice=ns ) q2 = elements.ChrPlasmaLens( - ds=0.176038957633108457, k=528.485181135649785, unit=1, nslice=ns + name="q2", ds=0.176038957633108457, k=528.485181135649785, unit=1, nslice=ns ) q3 = elements.ChrPlasmaLens( - ds=1.041842576046930486, k=3127.707468391874166, unit=1, nslice=ns + name="q3", ds=1.041842576046930486, k=3127.707468391874166, unit=1, nslice=ns ) q4 = elements.ChrPlasmaLens( - ds=0.334367090894399520, k=501.900417308233112, unit=1, nslice=ns + name="q4", ds=0.334367090894399520, k=501.900417308233112, unit=1, nslice=ns ) q5 = elements.ChrPlasmaLens( - ds=1.041842576046930486, k=3127.707468391874166, unit=1, nslice=ns + name="q5", ds=1.041842576046930486, k=3127.707468391874166, unit=1, nslice=ns ) q6 = elements.ChrPlasmaLens( - ds=0.176038957633108457, k=528.485181135649785, unit=1, nslice=ns + name="q6", ds=0.176038957633108457, k=528.485181135649785, unit=1, nslice=ns ) q7 = elements.ChrPlasmaLens( - ds=0.331817852986604588, k=996.147787384348956, unit=1, nslice=ns + name="q7", ds=0.331817852986604588, k=996.147787384348956, unit=1, nslice=ns ) -# q1 = elements.ChrPlasmaLens(ds=0.331817852986604588, k=2.98636067687944129, unit=0, nslice=ns) -# q2 = elements.ChrPlasmaLens(ds=0.176038957633108457, k=1.584350618697976110, unit=0, nslice=ns) -# q3 = elements.ChrPlasmaLens(ds=1.041842576046930486, k=9.37658318442237437, unit=0, nslice=ns) -# q4 = elements.ChrPlasmaLens(ds=0.334367090894399520, k=1.50465190902479784, unit=0, nslice=ns) -# q5 = elements.ChrPlasmaLens(ds=1.041842576046930486, k=9.37658318442237437, unit=0, nslice=ns) -# q6 = elements.ChrPlasmaLens(ds=0.176038957633108457, k=1.584350618697976110, unit=0, nslice=ns) -# q7 = elements.ChrPlasmaLens(ds=0.331817852986604588, k=2.98636067687944129, unit=0, nslice=ns) +# q1 = elements.ChrPlasmaLens(name="q1", ds=0.331817852986604588, k=2.98636067687944129, unit=0, nslice=ns) +# q2 = elements.ChrPlasmaLens(name="q2", ds=0.176038957633108457, k=1.584350618697976110, unit=0, nslice=ns) +# q3 = elements.ChrPlasmaLens(name="q3", ds=1.041842576046930486, k=9.37658318442237437, unit=0, nslice=ns) +# q4 = elements.ChrPlasmaLens(name="q4", ds=0.334367090894399520, k=1.50465190902479784, unit=0, nslice=ns) +# q5 = elements.ChrPlasmaLens(name="q5", ds=1.041842576046930486, k=9.37658318442237437, unit=0, nslice=ns) +# q6 = elements.ChrPlasmaLens(name="q6", ds=0.176038957633108457, k=1.584350618697976110, unit=0, nslice=ns) +# q7 = elements.ChrPlasmaLens(name="q7", ds=0.331817852986604588, k=2.98636067687944129, unit=0, nslice=ns) lattice_line = [ monitor, diff --git a/examples/cfchannel/run_cfchannel.py b/examples/cfchannel/run_cfchannel.py index b17d738ea..d46428dc0 100755 --- a/examples/cfchannel/run_cfchannel.py +++ b/examples/cfchannel/run_cfchannel.py @@ -47,7 +47,7 @@ sim.lattice.extend( [ monitor, - elements.ConstF(ds=2.0, kx=1.0, ky=1.0, kt=1.0), + elements.ConstF(name="constf1", ds=2.0, kx=1.0, ky=1.0, kt=1.0), monitor, ] ) diff --git a/examples/cfchannel/run_cfchannel_10nC_fft.py b/examples/cfchannel/run_cfchannel_10nC_fft.py index afac1caf7..9b6467929 100755 --- a/examples/cfchannel/run_cfchannel_10nC_fft.py +++ b/examples/cfchannel/run_cfchannel_10nC_fft.py @@ -53,7 +53,7 @@ sim.lattice.extend( [ monitor, - elements.ConstF(ds=2.0, kx=1.0, ky=1.0, kt=1.0, nslice=nslice), + elements.ConstF(name="constf1", ds=2.0, kx=1.0, ky=1.0, kt=1.0, nslice=nslice), monitor, ] ) diff --git a/examples/cfchannel/run_cfchannel_10nC_mlmg.py b/examples/cfchannel/run_cfchannel_10nC_mlmg.py index 771d76f12..c8c46d18a 100755 --- a/examples/cfchannel/run_cfchannel_10nC_mlmg.py +++ b/examples/cfchannel/run_cfchannel_10nC_mlmg.py @@ -52,7 +52,7 @@ sim.lattice.extend( [ monitor, - elements.ConstF(ds=2.0, kx=1.0, ky=1.0, kt=1.0, nslice=nslice), + elements.ConstF(name="constf1", ds=2.0, kx=1.0, ky=1.0, kt=1.0, nslice=nslice), monitor, ] ) diff --git a/examples/chicane/run_chicane.py b/examples/chicane/run_chicane.py index 10ff072eb..7065246ca 100644 --- a/examples/chicane/run_chicane.py +++ b/examples/chicane/run_chicane.py @@ -53,17 +53,17 @@ lb = 0.500194828041958 # bend arc length (meters) # Drift elements -dr1 = elements.Drift(ds=5.0058489435, nslice=ns) -dr2 = elements.Drift(ds=1.0, nslice=ns) -dr3 = elements.Drift(ds=2.0, nslice=ns) +dr1 = elements.Drift(name="dr1", ds=5.0058489435, nslice=ns) +dr2 = elements.Drift(name="dr2", ds=1.0, nslice=ns) +dr3 = elements.Drift(name="dr3", ds=2.0, nslice=ns) # Bend elements -sbend1 = elements.Sbend(ds=lb, rc=-rc, nslice=ns) -sbend2 = elements.Sbend(ds=lb, rc=rc, nslice=ns) +sbend1 = elements.Sbend(name="sbend1", ds=lb, rc=-rc, nslice=ns) +sbend2 = elements.Sbend(name="sbend2", ds=lb, rc=rc, nslice=ns) # Dipole Edge Focusing elements -dipedge1 = elements.DipEdge(psi=-psi, rc=-rc, g=0.0, K2=0.0) -dipedge2 = elements.DipEdge(psi=psi, rc=rc, g=0.0, K2=0.0) +dipedge1 = elements.DipEdge(name="dipedge1", psi=-psi, rc=-rc, g=0.0, K2=0.0) +dipedge2 = elements.DipEdge(name="dipedge2", psi=psi, rc=rc, g=0.0, K2=0.0) lattice_half = [sbend1, dipedge1, dr1, dipedge2, sbend2] # assign a segment with the first half of the lattice diff --git a/examples/chicane/run_chicane_csr.py b/examples/chicane/run_chicane_csr.py index 1ab675af8..9661d256d 100644 --- a/examples/chicane/run_chicane_csr.py +++ b/examples/chicane/run_chicane_csr.py @@ -55,17 +55,17 @@ lb = 0.500194828041958 # bend arc length (meters) # Drift elements -dr1 = elements.Drift(ds=5.0058489435, nslice=ns) -dr2 = elements.Drift(ds=1.0, nslice=ns) -dr3 = elements.Drift(ds=2.0, nslice=ns) +dr1 = elements.Drift(name="dr1", ds=5.0058489435, nslice=ns) +dr2 = elements.Drift(name="dr2", ds=1.0, nslice=ns) +dr3 = elements.Drift(name="dr3", ds=2.0, nslice=ns) # Bend elements -sbend1 = elements.Sbend(ds=lb, rc=-rc, nslice=ns) -sbend2 = elements.Sbend(ds=lb, rc=rc, nslice=ns) +sbend1 = elements.Sbend(name="sbend1", ds=lb, rc=-rc, nslice=ns) +sbend2 = elements.Sbend(name="sbend2", ds=lb, rc=rc, nslice=ns) # Dipole Edge Focusing elements -dipedge1 = elements.DipEdge(psi=-psi, rc=-rc, g=0.0, K2=0.0) -dipedge2 = elements.DipEdge(psi=psi, rc=rc, g=0.0, K2=0.0) +dipedge1 = elements.DipEdge(name="dipedge1", psi=-psi, rc=-rc, g=0.0, K2=0.0) +dipedge2 = elements.DipEdge(name="dipedge2", psi=psi, rc=rc, g=0.0, K2=0.0) lattice_half = [sbend1, dipedge1, dr1, dipedge2, sbend2] # assign a segment with the first half of the lattice diff --git a/examples/compression/run_compression.py b/examples/compression/run_compression.py index 16dc6d046..0552af292 100644 --- a/examples/compression/run_compression.py +++ b/examples/compression/run_compression.py @@ -47,9 +47,9 @@ # design the accelerator lattice sim.lattice.append(monitor) # Short RF cavity element -shortrf1 = elements.ShortRF(V=1000.0, freq=1.3e9, phase=-89.5) +shortrf1 = elements.ShortRF(name="shortrf1", V=1000.0, freq=1.3e9, phase=-89.5) # Drift element -drift1 = elements.Drift(ds=1.7) +drift1 = elements.Drift(name="drift1", ds=1.7) sim.lattice.extend([shortrf1, drift1]) diff --git a/examples/cyclotron/run_cyclotron.py b/examples/cyclotron/run_cyclotron.py index d194dd8e7..63ec87e1b 100755 --- a/examples/cyclotron/run_cyclotron.py +++ b/examples/cyclotron/run_cyclotron.py @@ -49,10 +49,10 @@ ns = 1 # number of slices per ds in the element period = [ monitor, - elements.ChrAcc(ds=0.038, ez=1.12188308693e-4, bz=1.0e-14, nslice=ns), - elements.ExactSbend(ds=0.25, phi=180.0, B=1), - elements.ChrAcc(ds=0.038, ez=1.12188308693e-4, bz=1.0e-14, nslice=ns), - elements.ExactSbend(ds=0.25, phi=180.0, B=1), + elements.ChrAcc(name="acc1", ds=0.038, ez=1.12188308693e-4, bz=1.0e-14, nslice=ns), + elements.ExactSbend(name="sbend1", ds=0.25, phi=180.0, B=1), + elements.ChrAcc(name="acc2", ds=0.038, ez=1.12188308693e-4, bz=1.0e-14, nslice=ns), + elements.ExactSbend(name="sbend2", ds=0.25, phi=180.0, B=1), monitor, ] diff --git a/examples/distgen/run_gaussian_twiss.py b/examples/distgen/run_gaussian_twiss.py index e317bc19d..dbd4c1ce7 100755 --- a/examples/distgen/run_gaussian_twiss.py +++ b/examples/distgen/run_gaussian_twiss.py @@ -52,15 +52,15 @@ ns = 25 # number of slices per ds in the element fodo = [ monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="d1", ds=0.25, nslice=ns), monitor, - elements.Quad(ds=1.0, k=1.0, nslice=ns), + elements.Quad(name="q1", ds=1.0, k=1.0, nslice=ns), monitor, - elements.Drift(ds=0.5, nslice=ns), + elements.Drift(name="d2", ds=0.5, nslice=ns), monitor, - elements.Quad(ds=1.0, k=-1.0, nslice=ns), + elements.Quad(name="q2", ds=1.0, k=-1.0, nslice=ns), monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="d3", ds=0.25, nslice=ns), monitor, ] # assign a fodo segment diff --git a/examples/distgen/run_kurth4d.py b/examples/distgen/run_kurth4d.py index 84bdc4d54..94194dcdb 100755 --- a/examples/distgen/run_kurth4d.py +++ b/examples/distgen/run_kurth4d.py @@ -50,7 +50,7 @@ # design the accelerator lattice) constf = [ monitor, - elements.ConstF(ds=2.0, kx=1.0, ky=1.0, kt=1.0e-4), + elements.ConstF(name="constf1", ds=2.0, kx=1.0, ky=1.0, kt=1.0e-4), monitor, ] diff --git a/examples/distgen/run_kvdist_twiss.py b/examples/distgen/run_kvdist_twiss.py index beaaec0de..7d67987e5 100755 --- a/examples/distgen/run_kvdist_twiss.py +++ b/examples/distgen/run_kvdist_twiss.py @@ -52,15 +52,15 @@ ns = 25 # number of slices per ds in the element fodo = [ monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="d1", ds=0.25, nslice=ns), monitor, - elements.Quad(ds=1.0, k=1.0, nslice=ns), + elements.Quad(name="q1", ds=1.0, k=1.0, nslice=ns), monitor, - elements.Drift(ds=0.5, nslice=ns), + elements.Drift(name="d2", ds=0.5, nslice=ns), monitor, - elements.Quad(ds=1.0, k=-1.0, nslice=ns), + elements.Quad(name="q2", ds=1.0, k=-1.0, nslice=ns), monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="d3", ds=0.25, nslice=ns), monitor, ] # assign a fodo segment diff --git a/examples/distgen/run_semigaussian.py b/examples/distgen/run_semigaussian.py index 3542d33b6..b737246f4 100755 --- a/examples/distgen/run_semigaussian.py +++ b/examples/distgen/run_semigaussian.py @@ -50,15 +50,15 @@ ns = 25 # number of slices per ds in the element fodo = [ monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="d1", ds=0.25, nslice=ns), monitor, - elements.Quad(ds=1.0, k=1.0, nslice=ns), + elements.Quad(name="q1", ds=1.0, k=1.0, nslice=ns), monitor, - elements.Drift(ds=0.5, nslice=ns), + elements.Drift(name="d2", ds=0.5, nslice=ns), monitor, - elements.Quad(ds=1.0, k=-1.0, nslice=ns), + elements.Quad(name="q2", ds=1.0, k=-1.0, nslice=ns), monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="d3", ds=0.25, nslice=ns), monitor, ] # assign a fodo segment diff --git a/examples/dogleg/run_dogleg.py b/examples/dogleg/run_dogleg.py index 96b9cd91f..f731c76ca 100644 --- a/examples/dogleg/run_dogleg.py +++ b/examples/dogleg/run_dogleg.py @@ -53,16 +53,16 @@ lb = 0.500194828041958 # bend arc length (meters) # Drift elements -dr1 = elements.Drift(ds=5.0058489435, nslice=ns) -dr2 = elements.Drift(ds=0.5, nslice=ns) +dr1 = elements.Drift(name="dr1", ds=5.0058489435, nslice=ns) +dr2 = elements.Drift(name="dr2", ds=0.5, nslice=ns) # Bend elements -sbend1 = elements.Sbend(ds=lb, rc=-rc, nslice=ns) -sbend2 = elements.Sbend(ds=lb, rc=rc, nslice=ns) +sbend1 = elements.Sbend(name="sbend1", ds=lb, rc=-rc, nslice=ns) +sbend2 = elements.Sbend(name="sbend2", ds=lb, rc=rc, nslice=ns) # Dipole Edge Focusing elements -dipedge1 = elements.DipEdge(psi=-psi, rc=-rc, g=0.0, K2=0.0) -dipedge2 = elements.DipEdge(psi=psi, rc=rc, g=0.0, K2=0.0) +dipedge1 = elements.DipEdge(name="dipedge1", psi=-psi, rc=-rc, g=0.0, K2=0.0) +dipedge2 = elements.DipEdge(name="dipedge2", psi=psi, rc=rc, g=0.0, K2=0.0) lattice_dogleg = [sbend1, dipedge1, dr1, dipedge2, sbend2, dr2] diff --git a/examples/epac2004_benchmarks/run_bithermal.py b/examples/epac2004_benchmarks/run_bithermal.py index 0f9a0bd8b..5463cf9e8 100755 --- a/examples/epac2004_benchmarks/run_bithermal.py +++ b/examples/epac2004_benchmarks/run_bithermal.py @@ -52,6 +52,7 @@ sim.lattice.append(monitor) constf = elements.ConstF( + name="constf", ds=10.0, kx=6.283185307179586, ky=6.283185307179586, diff --git a/examples/epac2004_benchmarks/run_fodo_rf_SC.py b/examples/epac2004_benchmarks/run_fodo_rf_SC.py index 03abc6386..a86cd7d06 100755 --- a/examples/epac2004_benchmarks/run_fodo_rf_SC.py +++ b/examples/epac2004_benchmarks/run_fodo_rf_SC.py @@ -50,14 +50,15 @@ sim.lattice.append(monitor) # Quad elements -fquad = elements.Quad(ds=0.15, k=2.4669749766168163, nslice=6) -dquad = elements.Quad(ds=0.3, k=-2.4669749766168163, nslice=12) +fquad = elements.Quad(name="fquad", ds=0.15, k=2.4669749766168163, nslice=6) +dquad = elements.Quad(name="dquad", ds=0.3, k=-2.4669749766168163, nslice=12) # Drift element -dr = elements.Drift(ds=0.1, nslice=4) +dr = elements.Drift(name="dr", ds=0.1, nslice=4) # RF cavity elements gapa1 = elements.RFCavity( + name="gapa1", ds=1.0, escale=0.042631556991578, freq=7.0e8, @@ -121,6 +122,7 @@ ) gapb1 = elements.RFCavity( + name="gapb1", ds=1.0, escale=0.042631556991578, freq=7.0e8, diff --git a/examples/expanding_beam/run_expanding_fft.py b/examples/expanding_beam/run_expanding_fft.py index d27958a5c..c6b9ac53b 100755 --- a/examples/expanding_beam/run_expanding_fft.py +++ b/examples/expanding_beam/run_expanding_fft.py @@ -55,7 +55,7 @@ monitor = elements.BeamMonitor("monitor", backend="h5") # design the accelerator lattice -sim.lattice.extend([monitor, elements.Drift(ds=6.0, nslice=40), monitor]) +sim.lattice.extend([monitor, elements.Drift(name="d1", ds=6.0, nslice=40), monitor]) # run simulation sim.evolve() diff --git a/examples/expanding_beam/run_expanding_mlmg.py b/examples/expanding_beam/run_expanding_mlmg.py index c41ada0e1..42b97904b 100755 --- a/examples/expanding_beam/run_expanding_mlmg.py +++ b/examples/expanding_beam/run_expanding_mlmg.py @@ -54,7 +54,7 @@ monitor = elements.BeamMonitor("monitor", backend="h5") # design the accelerator lattice -sim.lattice.extend([monitor, elements.Drift(ds=6.0, nslice=40), monitor]) +sim.lattice.extend([monitor, elements.Drift(name="d1", ds=6.0, nslice=40), monitor]) # run simulation sim.evolve() diff --git a/examples/fodo/run_fodo.py b/examples/fodo/run_fodo.py index 57703ed33..6a6418eca 100755 --- a/examples/fodo/run_fodo.py +++ b/examples/fodo/run_fodo.py @@ -50,15 +50,15 @@ ns = 25 # number of slices per ds in the element fodo = [ monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="drift1", ds=0.25, nslice=ns), monitor, - elements.Quad(ds=1.0, k=1.0, nslice=ns), + elements.Quad(name="quad1", ds=1.0, k=1.0, nslice=ns), monitor, - elements.Drift(ds=0.5, nslice=ns), + elements.Drift(name="drift2", ds=0.5, nslice=ns), monitor, - elements.Quad(ds=1.0, k=-1.0, nslice=ns), + elements.Quad(name="quad2", ds=1.0, k=-1.0, nslice=ns), monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="drift3", ds=0.25, nslice=ns), monitor, ] # assign a fodo segment diff --git a/examples/fodo/run_fodo_twiss.py b/examples/fodo/run_fodo_twiss.py index bd7b7c51d..700fdd767 100755 --- a/examples/fodo/run_fodo_twiss.py +++ b/examples/fodo/run_fodo_twiss.py @@ -52,15 +52,15 @@ ns = 25 # number of slices per ds in the element fodo = [ monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="drift1", ds=0.25, nslice=ns), monitor, - elements.Quad(ds=1.0, k=1.0, nslice=ns), + elements.Quad(name="quad1", ds=1.0, k=1.0, nslice=ns), monitor, - elements.Drift(ds=0.5, nslice=ns), + elements.Drift(name="drift2", ds=0.5, nslice=ns), monitor, - elements.Quad(ds=1.0, k=-1.0, nslice=ns), + elements.Quad(name="quad2", ds=1.0, k=-1.0, nslice=ns), monitor, - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="drift3", ds=0.25, nslice=ns), monitor, ] # assign a fodo segment diff --git a/examples/fodo_chromatic/run_fodo_chr.py b/examples/fodo_chromatic/run_fodo_chr.py index aa4677f75..1c25ff7c4 100755 --- a/examples/fodo_chromatic/run_fodo_chr.py +++ b/examples/fodo_chromatic/run_fodo_chr.py @@ -50,15 +50,15 @@ ns = 25 # number of slices per ds in the element fodo = [ monitor, - elements.ChrDrift(ds=0.25, nslice=ns), + elements.ChrDrift(name="drift1", ds=0.25, nslice=ns), monitor, - elements.ChrQuad(ds=1.0, k=1.0, nslice=ns), + elements.ChrQuad(name="quad1", ds=1.0, k=1.0, nslice=ns), monitor, - elements.ChrDrift(ds=0.5, nslice=ns), + elements.ChrDrift(name="drift2", ds=0.5, nslice=ns), monitor, - elements.ChrQuad(ds=1.0, k=-1.0, nslice=ns), + elements.ChrQuad(name="quad2", ds=1.0, k=-1.0, nslice=ns), monitor, - elements.ChrDrift(ds=0.25, nslice=ns), + elements.ChrDrift(name="drift3", ds=0.25, nslice=ns), monitor, ] # assign a fodo segment diff --git a/examples/fodo_programmable/run_fodo_programmable.py b/examples/fodo_programmable/run_fodo_programmable.py index dd9310608..b74e697f3 100755 --- a/examples/fodo_programmable/run_fodo_programmable.py +++ b/examples/fodo_programmable/run_fodo_programmable.py @@ -112,7 +112,7 @@ def my_ref_drift(pge, refpart): refpart.s = s + slice_ds -pge1 = elements.Programmable() +pge1 = elements.Programmable(name="d1") pge1.nslice = ns pge1.beam_particles = lambda pti, refpart: my_drift(pge1, pti, refpart) pge1.ref_particle = lambda refpart: my_ref_drift(pge1, refpart) @@ -121,7 +121,7 @@ def my_ref_drift(pge, refpart): # attention: assignment is a reference for pge2 = pge1 -pge2 = elements.Programmable() +pge2 = elements.Programmable(name="d2") pge2.nslice = ns pge2.beam_particles = lambda pti, refpart: my_drift(pge2, pti, refpart) pge2.ref_particle = lambda refpart: my_ref_drift(pge2, refpart) @@ -134,15 +134,15 @@ def my_ref_drift(pge, refpart): # design the accelerator lattice fodo = [ monitor, - pge1, # equivalent to elements.Drift(ds=0.25, nslice=ns) + pge1, # equivalent to elements.Drift("d1", ds=0.25, nslice=ns) monitor, - elements.Quad(ds=1.0, k=1.0, nslice=ns), + elements.Quad(name="q1", ds=1.0, k=1.0, nslice=ns), monitor, - pge2, # equivalent to elements.Drift(ds=0.5, nslice=ns) + pge2, # equivalent to elements.Drift("d2", ds=0.5, nslice=ns) monitor, - elements.Quad(ds=1.0, k=-1.0, nslice=ns), + elements.Quad(name="q2", ds=1.0, k=-1.0, nslice=ns), monitor, - pge1, # equivalent to elements.Drift(ds=0.25, nslice=ns) + pge1, # equivalent to elements.Drift("d1", ds=0.25, nslice=ns) monitor, ] # assign a fodo segment diff --git a/examples/fodo_rf/run_fodo_rf.py b/examples/fodo_rf/run_fodo_rf.py index 1eed9e10b..397e46212 100644 --- a/examples/fodo_rf/run_fodo_rf.py +++ b/examples/fodo_rf/run_fodo_rf.py @@ -47,12 +47,12 @@ # design the accelerator lattice sim.lattice.append(monitor) # Quad elements -quad1 = elements.Quad(ds=0.15, k=2.5) -quad2 = elements.Quad(ds=0.3, k=-2.5) +quad1 = elements.Quad(name="quad1", ds=0.15, k=2.5) +quad2 = elements.Quad(name="quad2", ds=0.3, k=-2.5) # Drift element -drift1 = elements.Drift(ds=1.0) +drift1 = elements.Drift(name="drift1", ds=1.0) # Short RF cavity element -shortrf1 = elements.Buncher(V=0.01, k=15.0) +shortrf1 = elements.Buncher(name="shortrf1", V=0.01, k=15.0) lattice_no_drifts = [quad1, shortrf1, quad2, shortrf1, quad1] # set first lattice element diff --git a/examples/fodo_tune/run_fodo_tune.py b/examples/fodo_tune/run_fodo_tune.py index 2315be15b..864a799d7 100755 --- a/examples/fodo_tune/run_fodo_tune.py +++ b/examples/fodo_tune/run_fodo_tune.py @@ -51,11 +51,11 @@ ns = 1 # number of slices per ds in the element fodo = [ monitor, - elements.Drift(ds=0.25, nslice=ns), - elements.Quad(ds=1.0, k=1.0, nslice=ns), - elements.Drift(ds=0.5, nslice=ns), - elements.Quad(ds=1.0, k=-1.0, nslice=ns), - elements.Drift(ds=0.25, nslice=ns), + elements.Drift(name="drift1", ds=0.25, nslice=ns), + elements.Quad(name="quad1", ds=1.0, k=1.0, nslice=ns), + elements.Drift(name="drift2", ds=0.5, nslice=ns), + elements.Quad(name="quad2", ds=1.0, k=-1.0, nslice=ns), + elements.Drift(name="drift3", ds=0.25, nslice=ns), ] # assign a fodo segment sim.lattice.extend(fodo) diff --git a/examples/initialize_from_array/run_from_array.py b/examples/initialize_from_array/run_from_array.py index c53eb3588..351ff95ab 100644 --- a/examples/initialize_from_array/run_from_array.py +++ b/examples/initialize_from_array/run_from_array.py @@ -98,7 +98,7 @@ sim.lattice.extend( [ monitor, - elements.Drift(ds=0.01), + elements.Drift(name="drift", ds=0.01), monitor, ] ) diff --git a/examples/iota_lattice/run_iotalattice.py b/examples/iota_lattice/run_iotalattice.py index 6cc6af2f0..5488cf1c7 100644 --- a/examples/iota_lattice/run_iotalattice.py +++ b/examples/iota_lattice/run_iotalattice.py @@ -46,57 +46,57 @@ ns = 10 # number of slices per ds in the element # Drift elements -dra1 = elements.Drift(ds=0.9125, nslice=ns) -dra2 = elements.Drift(ds=0.135, nslice=ns) -dra3 = elements.Drift(ds=0.725, nslice=ns) -dra4 = elements.Drift(ds=0.145, nslice=ns) -dra5 = elements.Drift(ds=0.3405, nslice=ns) -drb1 = elements.Drift(ds=0.3205, nslice=ns) -drb2 = elements.Drift(ds=0.14, nslice=ns) -drb3 = elements.Drift(ds=0.1525, nslice=ns) -drb4 = elements.Drift(ds=0.31437095, nslice=ns) -drc1 = elements.Drift(ds=0.42437095, nslice=ns) -drc2 = elements.Drift(ds=0.355, nslice=ns) -dnll = elements.Drift(ds=1.8, nslice=ns) -drd1 = elements.Drift(ds=0.62437095, nslice=ns) -drd2 = elements.Drift(ds=0.42, nslice=ns) -drd3 = elements.Drift(ds=1.625, nslice=ns) -drd4 = elements.Drift(ds=0.6305, nslice=ns) -dre1 = elements.Drift(ds=0.5305, nslice=ns) -dre2 = elements.Drift(ds=1.235, nslice=ns) -dre3 = elements.Drift(ds=0.8075, nslice=ns) +dra1 = elements.Drift(name="dra1", ds=0.9125, nslice=ns) +dra2 = elements.Drift(name="dra2", ds=0.135, nslice=ns) +dra3 = elements.Drift(name="dra3", ds=0.725, nslice=ns) +dra4 = elements.Drift(name="dra4", ds=0.145, nslice=ns) +dra5 = elements.Drift(name="dra5", ds=0.3405, nslice=ns) +drb1 = elements.Drift(name="drb1", ds=0.3205, nslice=ns) +drb2 = elements.Drift(name="drb2", ds=0.14, nslice=ns) +drb3 = elements.Drift(name="drb3", ds=0.1525, nslice=ns) +drb4 = elements.Drift(name="drb4", ds=0.31437095, nslice=ns) +drc1 = elements.Drift(name="drc1", ds=0.42437095, nslice=ns) +drc2 = elements.Drift(name="drc2", ds=0.355, nslice=ns) +dnll = elements.Drift(name="dnll", ds=1.8, nslice=ns) +drd1 = elements.Drift(name="drd1", ds=0.62437095, nslice=ns) +drd2 = elements.Drift(name="drd2", ds=0.42, nslice=ns) +drd3 = elements.Drift(name="drd3", ds=1.625, nslice=ns) +drd4 = elements.Drift(name="drd4", ds=0.6305, nslice=ns) +dre1 = elements.Drift(name="dre1", ds=0.5305, nslice=ns) +dre2 = elements.Drift(name="dre2", ds=1.235, nslice=ns) +dre3 = elements.Drift(name="dre3", ds=0.8075, nslice=ns) # Bend elements rc30 = 0.822230996255981 -sbend30 = elements.Sbend(ds=0.4305191429, rc=rc30) -edge30 = elements.DipEdge(psi=0.0, rc=rc30, g=0.058, K2=0.5) +sbend30 = elements.Sbend(name="sbend30", ds=0.4305191429, rc=rc30) +edge30 = elements.DipEdge(name="edge30", psi=0.0, rc=rc30, g=0.058, K2=0.5) rc60 = 0.772821121503940 -sbend60 = elements.Sbend(ds=0.8092963858, rc=rc60) -edge60 = elements.DipEdge(psi=0.0, rc=rc60, g=0.058, K2=0.5) +sbend60 = elements.Sbend(name="sbend60", ds=0.8092963858, rc=rc60) +edge60 = elements.DipEdge(name="edge60", psi=0.0, rc=rc60, g=0.058, K2=0.5) # Quad elements ds_quad = 0.21 -qa1 = elements.Quad(ds=ds_quad, k=-8.78017699, nslice=ns) -qa2 = elements.Quad(ds=ds_quad, k=13.24451745, nslice=ns) -qa3 = elements.Quad(ds=ds_quad, k=-13.65151327, nslice=ns) -qa4 = elements.Quad(ds=ds_quad, k=19.75138652, nslice=ns) -qb1 = elements.Quad(ds=ds_quad, k=-10.84199727, nslice=ns) -qb2 = elements.Quad(ds=ds_quad, k=16.24844348, nslice=ns) -qb3 = elements.Quad(ds=ds_quad, k=-8.27411104, nslice=ns) -qb4 = elements.Quad(ds=ds_quad, k=-7.45719247, nslice=ns) -qb5 = elements.Quad(ds=ds_quad, k=14.03362243, nslice=ns) -qb6 = elements.Quad(ds=ds_quad, k=-12.23595641, nslice=ns) -qc1 = elements.Quad(ds=ds_quad, k=-13.18863768, nslice=ns) -qc2 = elements.Quad(ds=ds_quad, k=11.50601829, nslice=ns) -qc3 = elements.Quad(ds=ds_quad, k=-11.10445869, nslice=ns) -qd1 = elements.Quad(ds=ds_quad, k=-6.78179218, nslice=ns) -qd2 = elements.Quad(ds=ds_quad, k=5.19026998, nslice=ns) -qd3 = elements.Quad(ds=ds_quad, k=-5.8586173, nslice=ns) -qd4 = elements.Quad(ds=ds_quad, k=4.62460039, nslice=ns) -qe1 = elements.Quad(ds=ds_quad, k=-4.49607687, nslice=ns) -qe2 = elements.Quad(ds=ds_quad, k=6.66737146, nslice=ns) -qe3 = elements.Quad(ds=ds_quad, k=-6.69148177, nslice=ns) +qa1 = elements.Quad(name="qa1", ds=ds_quad, k=-8.78017699, nslice=ns) +qa2 = elements.Quad(name="qa2", ds=ds_quad, k=13.24451745, nslice=ns) +qa3 = elements.Quad(name="qa3", ds=ds_quad, k=-13.65151327, nslice=ns) +qa4 = elements.Quad(name="qa4", ds=ds_quad, k=19.75138652, nslice=ns) +qb1 = elements.Quad(name="qb1", ds=ds_quad, k=-10.84199727, nslice=ns) +qb2 = elements.Quad(name="qb2", ds=ds_quad, k=16.24844348, nslice=ns) +qb3 = elements.Quad(name="qb3", ds=ds_quad, k=-8.27411104, nslice=ns) +qb4 = elements.Quad(name="qb4", ds=ds_quad, k=-7.45719247, nslice=ns) +qb5 = elements.Quad(name="qb5", ds=ds_quad, k=14.03362243, nslice=ns) +qb6 = elements.Quad(name="qb6", ds=ds_quad, k=-12.23595641, nslice=ns) +qc1 = elements.Quad(name="qc1", ds=ds_quad, k=-13.18863768, nslice=ns) +qc2 = elements.Quad(name="qc2", ds=ds_quad, k=11.50601829, nslice=ns) +qc3 = elements.Quad(name="qc3", ds=ds_quad, k=-11.10445869, nslice=ns) +qd1 = elements.Quad(name="qd1", ds=ds_quad, k=-6.78179218, nslice=ns) +qd2 = elements.Quad(name="qd2", ds=ds_quad, k=5.19026998, nslice=ns) +qd3 = elements.Quad(name="qd3", ds=ds_quad, k=-5.8586173, nslice=ns) +qd4 = elements.Quad(name="qd4", ds=ds_quad, k=4.62460039, nslice=ns) +qe1 = elements.Quad(name="qe1", ds=ds_quad, k=-4.49607687, nslice=ns) +qe2 = elements.Quad(name="qe2", ds=ds_quad, k=6.66737146, nslice=ns) +qe3 = elements.Quad(name="qe3", ds=ds_quad, k=-6.69148177, nslice=ns) # build lattice: first half, qe3, then mirror # fmt: off diff --git a/examples/iota_lattice/run_iotalattice_sdep.py b/examples/iota_lattice/run_iotalattice_sdep.py index 49cd567fa..70f50d101 100644 --- a/examples/iota_lattice/run_iotalattice_sdep.py +++ b/examples/iota_lattice/run_iotalattice_sdep.py @@ -56,57 +56,57 @@ ns = 10 # number of slices per ds in the element # Drift elements -dra1 = elements.Drift(ds=0.9125, nslice=ns) -dra2 = elements.Drift(ds=0.135, nslice=ns) -dra3 = elements.Drift(ds=0.725, nslice=ns) -dra4 = elements.Drift(ds=0.145, nslice=ns) -dra5 = elements.Drift(ds=0.3405, nslice=ns) -drb1 = elements.Drift(ds=0.3205, nslice=ns) -drb2 = elements.Drift(ds=0.14, nslice=ns) -drb3 = elements.Drift(ds=0.1525, nslice=ns) -drb4 = elements.Drift(ds=0.31437095, nslice=ns) -drc1 = elements.Drift(ds=0.42437095, nslice=ns) -drc2 = elements.Drift(ds=0.355, nslice=ns) -dnll = elements.Drift(ds=1.8, nslice=ns) -drd1 = elements.Drift(ds=0.62437095, nslice=ns) -drd2 = elements.Drift(ds=0.42, nslice=ns) -drd3 = elements.Drift(ds=1.625, nslice=ns) -drd4 = elements.Drift(ds=0.6305, nslice=ns) -dre1 = elements.Drift(ds=0.5305, nslice=ns) -dre2 = elements.Drift(ds=1.235, nslice=ns) -dre3 = elements.Drift(ds=0.8075, nslice=ns) +dra1 = elements.Drift(name="dra1", ds=0.9125, nslice=ns) +dra2 = elements.Drift(name="dra2", ds=0.135, nslice=ns) +dra3 = elements.Drift(name="dra3", ds=0.725, nslice=ns) +dra4 = elements.Drift(name="dra4", ds=0.145, nslice=ns) +dra5 = elements.Drift(name="dra5", ds=0.3405, nslice=ns) +drb1 = elements.Drift(name="drb1", ds=0.3205, nslice=ns) +drb2 = elements.Drift(name="drb2", ds=0.14, nslice=ns) +drb3 = elements.Drift(name="drb3", ds=0.1525, nslice=ns) +drb4 = elements.Drift(name="drb4", ds=0.31437095, nslice=ns) +drc1 = elements.Drift(name="drc1", ds=0.42437095, nslice=ns) +drc2 = elements.Drift(name="drc2", ds=0.355, nslice=ns) +dnll = elements.Drift(name="dnll", ds=1.8, nslice=ns) +drd1 = elements.Drift(name="drd1", ds=0.62437095, nslice=ns) +drd2 = elements.Drift(name="drd2", ds=0.42, nslice=ns) +drd3 = elements.Drift(name="drd3", ds=1.625, nslice=ns) +drd4 = elements.Drift(name="drd4", ds=0.6305, nslice=ns) +dre1 = elements.Drift(name="dre1", ds=0.5305, nslice=ns) +dre2 = elements.Drift(name="dre2", ds=1.235, nslice=ns) +dre3 = elements.Drift(name="dre3", ds=0.8075, nslice=ns) # Bend elements rc30 = 0.822230996255981 -sbend30 = elements.Sbend(ds=0.4305191429, rc=rc30) -edge30 = elements.DipEdge(psi=0.0, rc=rc30, g=0.058, K2=0.5) +sbend30 = elements.Sbend(name="sbend30", ds=0.4305191429, rc=rc30) +edge30 = elements.DipEdge(name="edge30", psi=0.0, rc=rc30, g=0.058, K2=0.5) rc60 = 0.772821121503940 -sbend60 = elements.Sbend(ds=0.8092963858, rc=rc60) -edge60 = elements.DipEdge(psi=0.0, rc=rc60, g=0.058, K2=0.5) +sbend60 = elements.Sbend(name="sbend60", ds=0.8092963858, rc=rc60) +edge60 = elements.DipEdge(name="edge60", psi=0.0, rc=rc60, g=0.058, K2=0.5) # Quad elements ds_quad = 0.21 -qa1 = elements.Quad(ds=ds_quad, k=-8.78017699, nslice=ns) -qa2 = elements.Quad(ds=ds_quad, k=13.24451745, nslice=ns) -qa3 = elements.Quad(ds=ds_quad, k=-13.65151327, nslice=ns) -qa4 = elements.Quad(ds=ds_quad, k=19.75138652, nslice=ns) -qb1 = elements.Quad(ds=ds_quad, k=-10.84199727, nslice=ns) -qb2 = elements.Quad(ds=ds_quad, k=16.24844348, nslice=ns) -qb3 = elements.Quad(ds=ds_quad, k=-8.27411104, nslice=ns) -qb4 = elements.Quad(ds=ds_quad, k=-7.45719247, nslice=ns) -qb5 = elements.Quad(ds=ds_quad, k=14.03362243, nslice=ns) -qb6 = elements.Quad(ds=ds_quad, k=-12.23595641, nslice=ns) -qc1 = elements.Quad(ds=ds_quad, k=-13.18863768, nslice=ns) -qc2 = elements.Quad(ds=ds_quad, k=11.50601829, nslice=ns) -qc3 = elements.Quad(ds=ds_quad, k=-11.10445869, nslice=ns) -qd1 = elements.Quad(ds=ds_quad, k=-6.78179218, nslice=ns) -qd2 = elements.Quad(ds=ds_quad, k=5.19026998, nslice=ns) -qd3 = elements.Quad(ds=ds_quad, k=-5.8586173, nslice=ns) -qd4 = elements.Quad(ds=ds_quad, k=4.62460039, nslice=ns) -qe1 = elements.Quad(ds=ds_quad, k=-4.49607687, nslice=ns) -qe2 = elements.Quad(ds=ds_quad, k=6.66737146, nslice=ns) -qe3 = elements.Quad(ds=ds_quad, k=-6.69148177, nslice=ns) +qa1 = elements.Quad(name="qa1", ds=ds_quad, k=-8.78017699, nslice=ns) +qa2 = elements.Quad(name="qa2", ds=ds_quad, k=13.24451745, nslice=ns) +qa3 = elements.Quad(name="qa3", ds=ds_quad, k=-13.65151327, nslice=ns) +qa4 = elements.Quad(name="qa4", ds=ds_quad, k=19.75138652, nslice=ns) +qb1 = elements.Quad(name="qb1", ds=ds_quad, k=-10.84199727, nslice=ns) +qb2 = elements.Quad(name="qb2", ds=ds_quad, k=16.24844348, nslice=ns) +qb3 = elements.Quad(name="qb3", ds=ds_quad, k=-8.27411104, nslice=ns) +qb4 = elements.Quad(name="qb4", ds=ds_quad, k=-7.45719247, nslice=ns) +qb5 = elements.Quad(name="qb5", ds=ds_quad, k=14.03362243, nslice=ns) +qb6 = elements.Quad(name="qb6", ds=ds_quad, k=-12.23595641, nslice=ns) +qc1 = elements.Quad(name="qc1", ds=ds_quad, k=-13.18863768, nslice=ns) +qc2 = elements.Quad(name="qc2", ds=ds_quad, k=11.50601829, nslice=ns) +qc3 = elements.Quad(name="qc3", ds=ds_quad, k=-11.10445869, nslice=ns) +qd1 = elements.Quad(name="qd1", ds=ds_quad, k=-6.78179218, nslice=ns) +qd2 = elements.Quad(name="qd2", ds=ds_quad, k=5.19026998, nslice=ns) +qd3 = elements.Quad(name="qd3", ds=ds_quad, k=-5.8586173, nslice=ns) +qd4 = elements.Quad(name="qd4", ds=ds_quad, k=4.62460039, nslice=ns) +qe1 = elements.Quad(name="qe1", ds=ds_quad, k=-4.49607687, nslice=ns) +qe2 = elements.Quad(name="qe2", ds=ds_quad, k=6.66737146, nslice=ns) +qe3 = elements.Quad(name="qe3", ds=ds_quad, k=-6.69148177, nslice=ns) # Special (elliptic) nonlinear element: @@ -120,7 +120,7 @@ # build up the nonlinear lens in segments ds_half = ds / 2.0 -dr = elements.Drift(ds=ds_half, nslice=1) +dr = elements.Drift(name="dr", ds=ds_half, nslice=1) nll = [] for j in range(0, num_lenses): s = -lens_length / 2.0 + ds_half + j * ds @@ -130,7 +130,7 @@ ) knll_s = t_strength * c_parameter**2 * ds / beta cnll_s = c_parameter * math.sqrt(beta) - nllens = elements.NonlinearLens(knll=knll_s, cnll=cnll_s) + nllens = elements.NonlinearLens(name="nllens" + str(j), knll=knll_s, cnll=cnll_s) segment = [dr, nllens, dr] nll.extend(segment) diff --git a/examples/iota_lens/run_iotalens.py b/examples/iota_lens/run_iotalens.py index 96a02118f..3efcd826f 100644 --- a/examples/iota_lens/run_iotalens.py +++ b/examples/iota_lens/run_iotalens.py @@ -48,9 +48,9 @@ monitor.cn = 0.01 # design the accelerator lattice -constEnd = elements.ConstF(ds=0.05, kx=1.0, ky=1.0, kt=1.0e-12) -nllens = elements.NonlinearLens(knll=4.0e-6, cnll=0.01) -const = elements.ConstF(ds=0.1, kx=1.0, ky=1.0, kt=1.0e-12) +constEnd = elements.ConstF(name="constEnd", ds=0.05, kx=1.0, ky=1.0, kt=1.0e-12) +nllens = elements.NonlinearLens(name="nllens", knll=4.0e-6, cnll=0.01) +const = elements.ConstF(name="const", ds=0.1, kx=1.0, ky=1.0, kt=1.0e-12) num_lenses = 18 nllens_lattice = ( diff --git a/examples/iota_lens/run_iotalens_sdep.py b/examples/iota_lens/run_iotalens_sdep.py index a078a27b0..40f147062 100644 --- a/examples/iota_lens/run_iotalens_sdep.py +++ b/examples/iota_lens/run_iotalens_sdep.py @@ -65,7 +65,7 @@ # drift elements ds_half = ds / 2.0 -dr = elements.Drift(ds=ds_half) +dr = elements.Drift(name="dr", ds=ds_half) # define the nonlinear lens segments for j in range(0, num_lenses): @@ -76,13 +76,18 @@ ) knll_s = t_strength * c_parameter**2 * ds / beta cnll_s = c_parameter * math.sqrt(beta) - nllens = elements.NonlinearLens(knll=knll_s, cnll=cnll_s) + nllens = elements.NonlinearLens(name="nllens" + str(j), knll=knll_s, cnll=cnll_s) segments = [dr, nllens, dr] sim.lattice.extend(segments) # focusing lens const = elements.ConstF( - ds=1.0e-8, kx=12060.113295833, ky=12060.113295833, kt=1.0e-12, nslice=1 + name="const", + ds=1.0e-8, + kx=12060.113295833, + ky=12060.113295833, + kt=1.0e-12, + nslice=1, ) sim.lattice.append(const) sim.lattice.append(monitor) diff --git a/examples/kicker/run_kicker.py b/examples/kicker/run_kicker.py index 77cc624ea..c21a00f6c 100644 --- a/examples/kicker/run_kicker.py +++ b/examples/kicker/run_kicker.py @@ -46,8 +46,8 @@ # design the accelerator lattice kicklattice = [ monitor, - elements.Kicker(xkick=2.0e-3, ykick=0.0, unit="dimensionless"), - elements.Kicker(xkick=0.0, ykick=3.0e-3, unit="dimensionless"), + elements.Kicker(name="kick1", xkick=2.0e-3, ykick=0.0, unit="dimensionless"), + elements.Kicker(name="kick2", xkick=0.0, ykick=3.0e-3, unit="dimensionless"), monitor, ] # assign a lattice diff --git a/examples/kurth/run_kurth_10nC_periodic.py b/examples/kurth/run_kurth_10nC_periodic.py index b819a8ecb..62b3be319 100755 --- a/examples/kurth/run_kurth_10nC_periodic.py +++ b/examples/kurth/run_kurth_10nC_periodic.py @@ -47,8 +47,8 @@ # design the accelerator lattice nslice = 20 # use 30 for increased precision -constf1 = elements.ConstF(ds=2.0, kx=0.7, ky=0.7, kt=0.7, nslice=nslice) -drift1 = elements.Drift(ds=1.0, nslice=nslice) +constf1 = elements.ConstF(name="constf1", ds=2.0, kx=0.7, ky=0.7, kt=0.7, nslice=nslice) +drift1 = elements.Drift(name="drift1", ds=1.0, nslice=nslice) sim.lattice.extend([monitor, drift1, constf1, drift1, monitor]) # run simulation diff --git a/examples/kurth/run_kurth_periodic.py b/examples/kurth/run_kurth_periodic.py index 1d4d45aa1..6b6f60f0d 100755 --- a/examples/kurth/run_kurth_periodic.py +++ b/examples/kurth/run_kurth_periodic.py @@ -45,8 +45,8 @@ monitor = elements.BeamMonitor("monitor", backend="h5") # design the accelerator lattice -constf1 = elements.ConstF(ds=2.0, kx=0.7, ky=0.7, kt=0.7) -drift1 = elements.Drift(ds=1.0) +constf1 = elements.ConstF(name="constf1", ds=2.0, kx=0.7, ky=0.7, kt=0.7) +drift1 = elements.Drift(name="drift1", ds=1.0) sim.lattice.extend([monitor, drift1, constf1, drift1, monitor]) # run simulation diff --git a/examples/multipole/run_multipole.py b/examples/multipole/run_multipole.py index 656f751cb..a8a065351 100644 --- a/examples/multipole/run_multipole.py +++ b/examples/multipole/run_multipole.py @@ -46,9 +46,11 @@ # design the accelerator lattice multipole = [ monitor, - elements.Multipole(multipole=2, K_normal=3.0, K_skew=0.0), - elements.Multipole(multipole=3, K_normal=100.0, K_skew=-50.0), - elements.Multipole(multipole=4, K_normal=65.0, K_skew=6.0), + elements.Multipole(name="thin_quadrupole", multipole=2, K_normal=3.0, K_skew=0.0), + elements.Multipole( + name="thin_sextupole", multipole=3, K_normal=100.0, K_skew=-50.0 + ), + elements.Multipole(name="thin_octupole", multipole=4, K_normal=65.0, K_skew=6.0), monitor, ] # assign a fodo segment diff --git a/examples/optimize_triplet/run_triplet.py b/examples/optimize_triplet/run_triplet.py index 0766e315a..dc7466d15 100755 --- a/examples/optimize_triplet/run_triplet.py +++ b/examples/optimize_triplet/run_triplet.py @@ -43,13 +43,13 @@ def build_lattice(parameters: tuple, write_particles: bool) -> list: # enforce a mirror symmetry of the triplet line = [ - elements.Drift(ds=2.7, nslice=ns), - elements.Quad(ds=0.1, k=q1_k, nslice=ns), - elements.Drift(ds=1.4, nslice=ns), - elements.Quad(ds=0.2, k=q2_k, nslice=ns), - elements.Drift(ds=1.4, nslice=ns), - elements.Quad(ds=0.1, k=q1_k, nslice=ns), - elements.Drift(ds=2.7, nslice=ns), + elements.Drift(name="drift1", ds=2.7, nslice=ns), + elements.Quad(name="quad1", ds=0.1, k=q1_k, nslice=ns), + elements.Drift(name="drift2", ds=1.4, nslice=ns), + elements.Quad(name="quad2", ds=0.2, k=q2_k, nslice=ns), + elements.Drift(name="drift3", ds=1.4, nslice=ns), + elements.Quad(name="quad1", ds=0.1, k=q1_k, nslice=ns), + elements.Drift(name="drift4", ds=2.7, nslice=ns), ] if write_particles: diff --git a/examples/positron_channel/run_positron.py b/examples/positron_channel/run_positron.py index 069edcc0f..0f98ae161 100755 --- a/examples/positron_channel/run_positron.py +++ b/examples/positron_channel/run_positron.py @@ -50,14 +50,16 @@ ns = 1 # number of slices per ds in the element period = [ monitor, - elements.ChrQuad(ds=0.1, k=-6.674941, unit=1, nslice=ns), - elements.ChrDrift(ds=0.3, nslice=ns), - elements.ChrQuad(ds=0.2, k=6.674941, unit=1, nslice=ns), - elements.ChrDrift(ds=0.3, nslice=ns), - elements.ChrQuad(ds=0.1, k=-6.674941, unit=1, nslice=ns), - elements.ChrDrift(ds=0.1, nslice=ns), - elements.ChrAcc(ds=1.8, ez=10871.950994502130424, bz=1.0e-12, nslice=ns), - elements.ChrDrift(ds=0.1, nslice=ns), + elements.ChrQuad(name="quad1", ds=0.1, k=-6.674941, unit=1, nslice=ns), + elements.ChrDrift(name="drift1", ds=0.3, nslice=ns), + elements.ChrQuad(name="quad2", ds=0.2, k=6.674941, unit=1, nslice=ns), + elements.ChrDrift(name="drift2", ds=0.3, nslice=ns), + elements.ChrQuad(name="quad3", ds=0.1, k=-6.674941, unit=1, nslice=ns), + elements.ChrDrift(name="drift3", ds=0.1, nslice=ns), + elements.ChrAcc( + name="acc", ds=1.8, ez=10871.950994502130424, bz=1.0e-12, nslice=ns + ), + elements.ChrDrift(name="drift4", ds=0.1, nslice=ns), monitor, ] diff --git a/examples/quadrupole_softedge/run_quadrupole_softedge.py b/examples/quadrupole_softedge/run_quadrupole_softedge.py index 055d19080..8f74a3241 100755 --- a/examples/quadrupole_softedge/run_quadrupole_softedge.py +++ b/examples/quadrupole_softedge/run_quadrupole_softedge.py @@ -50,6 +50,7 @@ ns = 1 # number of slices per ds in the element quad1 = elements.SoftQuadrupole( + name="quad1", ds=1.0, gscale=1.0, cos_coefficients=[2], @@ -59,6 +60,7 @@ ) quad2 = elements.SoftQuadrupole( + name="quad2", ds=1.0, gscale=-1.0, cos_coefficients=[2], @@ -67,8 +69,8 @@ nslice=ns, ) -drift1 = elements.Drift(ds=0.25, nslice=ns) -drift2 = elements.Drift(ds=0.5, nslice=ns) +drift1 = elements.Drift(name="drift1", ds=0.25, nslice=ns) +drift2 = elements.Drift(name="drift2", ds=0.5, nslice=ns) # assign a fodo segment sim.lattice.extend([monitor, drift1, quad1, drift2, quad2, drift1, monitor]) diff --git a/examples/rfcavity/run_rfcavity.py b/examples/rfcavity/run_rfcavity.py index acdba68b4..af73ed12c 100755 --- a/examples/rfcavity/run_rfcavity.py +++ b/examples/rfcavity/run_rfcavity.py @@ -47,10 +47,11 @@ # design the accelerator lattice # Drift elements -dr1 = elements.Drift(ds=0.4, nslice=1) -dr2 = elements.Drift(ds=0.032997, nslice=1) +dr1 = elements.Drift(name="dr1", ds=0.4, nslice=1) +dr2 = elements.Drift(name="dr2", ds=0.032997, nslice=1) # RF cavity element rf = elements.RFCavity( + name="rf", ds=1.31879807, escale=62.0, freq=1.3e9, diff --git a/examples/rotation/run_rotation.py b/examples/rotation/run_rotation.py index a1257b302..0f1f187d1 100644 --- a/examples/rotation/run_rotation.py +++ b/examples/rotation/run_rotation.py @@ -46,9 +46,9 @@ # design the accelerator lattice rotated_drift = [ monitor, - elements.PRot(phi_in=0.0, phi_out=-5.0), - elements.Drift(ds=2.0, nslice=1), - elements.PRot(phi_in=-5.0, phi_out=0.0), + elements.PRot(name="rotation1", phi_in=0.0, phi_out=-5.0), + elements.Drift(name="drift1", ds=2.0, nslice=1), + elements.PRot(name="rotation2", phi_in=-5.0, phi_out=0.0), monitor, ] # assign a lattice segment diff --git a/examples/solenoid/run_solenoid.py b/examples/solenoid/run_solenoid.py index 78f02100a..fc0c517b4 100755 --- a/examples/solenoid/run_solenoid.py +++ b/examples/solenoid/run_solenoid.py @@ -48,7 +48,7 @@ sim.lattice.extend( [ monitor, - elements.Sol(ds=3.820395, ks=0.8223219329893234), + elements.Sol(name="sol1", ds=3.820395, ks=0.8223219329893234), monitor, ] ) diff --git a/examples/solenoid_softedge/run_solenoid_softedge.py b/examples/solenoid_softedge/run_solenoid_softedge.py index 0d93a7f31..c56aa236c 100755 --- a/examples/solenoid_softedge/run_solenoid_softedge.py +++ b/examples/solenoid_softedge/run_solenoid_softedge.py @@ -43,6 +43,7 @@ # design the accelerator lattice sol = elements.SoftSolenoid( + name="sol1", ds=6.0, bscale=1.233482899483985, cos_coefficients=[ diff --git a/examples/thin_dipole/run_thin_dipole.py b/examples/thin_dipole/run_thin_dipole.py index e29b320e7..4df695f9a 100755 --- a/examples/thin_dipole/run_thin_dipole.py +++ b/examples/thin_dipole/run_thin_dipole.py @@ -48,13 +48,15 @@ # design the accelerator lattice) ns = 1 # number of slices per ds in the element segment = [ - elements.Drift(ds=0.003926990816987, nslice=ns), - elements.ThinDipole(theta=0.45, rc=1.0), - elements.Drift(ds=0.003926990816987, nslice=ns), + elements.Drift(name="drift1", ds=0.003926990816987, nslice=ns), + elements.ThinDipole(name="kick", theta=0.45, rc=1.0), + elements.Drift(name="drift2", ds=0.003926990816987, nslice=ns), ] bend = 200 * segment -inverse_bend = elements.ExactSbend(ds=-1.570796326794897, phi=-90.0) +inverse_bend = elements.ExactSbend( + name="inverse_bend", ds=-1.570796326794897, phi=-90.0 +) sim.lattice.append(monitor) sim.lattice.extend(bend) diff --git a/src/initialization/InitElement.cpp b/src/initialization/InitElement.cpp index 9c5afd6b6..dd770e51f 100644 --- a/src/initialization/InitElement.cpp +++ b/src/initialization/InitElement.cpp @@ -123,13 +123,13 @@ namespace detail amrex::ParticleReal k; pp_element.get("k", k); - m_lattice.emplace_back( Quad(ds, k, a["dx"], a["dy"], a["rotation_degree"], nslice) ); + m_lattice.emplace_back( Quad(ds, k, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "drift") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); - m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], nslice) ); + m_lattice.emplace_back( Drift(ds, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "sbend") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -138,7 +138,7 @@ namespace detail amrex::ParticleReal rc; pp_element.get("rc", rc); - m_lattice.emplace_back( Sbend(ds, rc, a["dx"], a["dy"], a["rotation_degree"], nslice) ); + m_lattice.emplace_back( Sbend(ds, rc, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "cfbend") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -148,7 +148,7 @@ namespace detail 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) ); + m_lattice.emplace_back( CFbend(ds, rc, k, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "dipedge") { auto a = detail::query_alignment(pp_element); @@ -159,7 +159,7 @@ namespace detail pp_element.get("g", g); pp_element.get("K2", K2); - m_lattice.emplace_back( DipEdge(psi, rc, g, K2, a["dx"], a["dy"], a["rotation_degree"]) ); + m_lattice.emplace_back( DipEdge(psi, rc, g, K2, a["dx"], a["dy"], a["rotation_degree"], element_name) ); } else if (element_type == "constf") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -170,7 +170,7 @@ namespace detail 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) ); + m_lattice.emplace_back( ConstF(ds, kx, ky, kt, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "buncher") { auto a = detail::query_alignment(pp_element); @@ -179,7 +179,7 @@ namespace detail pp_element.get("V", V); pp_element.get("k", k); - m_lattice.emplace_back( Buncher(V, k, a["dx"], a["dy"], a["rotation_degree"]) ); + m_lattice.emplace_back( Buncher(V, k, a["dx"], a["dy"], a["rotation_degree"], element_name) ); } else if (element_type == "shortrf") { auto a = detail::query_alignment(pp_element); @@ -190,7 +190,7 @@ namespace detail pp_element.get("freq", freq); pp_element.queryAdd("phase", phase); - m_lattice.emplace_back( ShortRF(V, freq, phase, a["dx"], a["dy"], a["rotation_degree"]) ); + m_lattice.emplace_back( ShortRF(V, freq, phase, a["dx"], a["dy"], a["rotation_degree"], element_name) ); } else if (element_type == "multipole") { auto a = detail::query_alignment(pp_element); @@ -201,7 +201,7 @@ namespace detail pp_element.get("k_normal", k_normal); pp_element.get("k_skew", k_skew); - m_lattice.emplace_back( Multipole(m, k_normal, k_skew, a["dx"], a["dy"], a["rotation_degree"]) ); + m_lattice.emplace_back( Multipole(m, k_normal, k_skew, a["dx"], a["dy"], a["rotation_degree"], element_name) ); } else if (element_type == "nonlinear_lens") { auto a = detail::query_alignment(pp_element); @@ -210,7 +210,7 @@ namespace detail pp_element.get("knll", knll); pp_element.get("cnll", cnll); - m_lattice.emplace_back( NonlinearLens(knll, cnll, a["dx"], a["dy"], a["rotation_degree"]) ); + m_lattice.emplace_back( NonlinearLens(knll, cnll, a["dx"], a["dy"], a["rotation_degree"], element_name) ); } else if (element_type == "rfcavity") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -228,7 +228,7 @@ 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) ); + m_lattice.emplace_back( RFCavity(ds, escale, freq, phase, cos_coef, sin_coef, a["dx"], a["dy"], a["rotation_degree"], mapsteps, nslice, element_name) ); } else if (element_type == "solenoid") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -237,14 +237,14 @@ namespace detail amrex::ParticleReal ks; pp_element.get("ks", ks); - m_lattice.emplace_back( Sol(ds, ks, a["dx"], a["dy"], a["rotation_degree"], nslice) ); + m_lattice.emplace_back( Sol(ds, ks, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "prot") { amrex::ParticleReal phi_in, phi_out; pp_element.get("phi_in", phi_in); pp_element.get("phi_out", phi_out); - m_lattice.emplace_back( PRot(phi_in, phi_out) ); + m_lattice.emplace_back( PRot(phi_in, phi_out, element_name) ); } else if (element_type == "solenoid_softedge") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -262,7 +262,7 @@ 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) ); + m_lattice.emplace_back( SoftSolenoid(ds, bscale, cos_coef, sin_coef, units, a["dx"], a["dy"], a["rotation_degree"], mapsteps, nslice, element_name) ); } else if (element_type == "quadrupole_softedge") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -278,13 +278,13 @@ 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) ); + m_lattice.emplace_back( SoftQuadrupole(ds, gscale, cos_coef, sin_coef, a["dx"], a["dy"], a["rotation_degree"], 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); - m_lattice.emplace_back( ChrDrift(ds, a["dx"], a["dy"], a["rotation_degree"], nslice) ); + m_lattice.emplace_back( ChrDrift(ds, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "quad_chromatic") { auto a = detail::query_alignment(pp_element); @@ -295,7 +295,7 @@ 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) ); + m_lattice.emplace_back( ChrQuad(ds, k, units, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "plasma_lens_chromatic") { auto a = detail::query_alignment(pp_element); @@ -306,7 +306,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) ); + m_lattice.emplace_back( ChrPlasmaLens(ds, k, units, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "tapered_plasma_lens") { auto a = detail::query_alignment(pp_element); @@ -318,13 +318,13 @@ namespace detail pp_element.get("taper", taper); pp_element.queryAdd("units", units); - m_lattice.emplace_back( TaperedPL(k, taper, units, a["dx"], a["dy"], a["rotation_degree"]) ); + m_lattice.emplace_back( TaperedPL(k, taper, units, a["dx"], a["dy"], a["rotation_degree"], element_name) ); } else if (element_type == "drift_exact") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); auto a = detail::query_alignment(pp_element); - m_lattice.emplace_back( ExactDrift(ds, a["dx"], a["dy"], a["rotation_degree"], nslice) ); + m_lattice.emplace_back( ExactDrift(ds, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "sbend_exact") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -335,7 +335,7 @@ namespace detail 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) ); + m_lattice.emplace_back( ExactSbend(ds, phi, B, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "uniform_acc_chromatic") { auto const [ds, nslice] = detail::query_ds(pp_element, nslice_default); @@ -345,7 +345,7 @@ namespace detail 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) ); + m_lattice.emplace_back( ChrAcc(ds, ez, bz, a["dx"], a["dy"], a["rotation_degree"], nslice, element_name) ); } else if (element_type == "thin_dipole") { auto a = detail::query_alignment(pp_element); @@ -354,7 +354,7 @@ namespace detail pp_element.get("theta", theta); pp_element.get("rc", rc); - m_lattice.emplace_back( ThinDipole(theta, rc, a["dx"], a["dy"], a["rotation_degree"]) ); + m_lattice.emplace_back( ThinDipole(theta, rc, a["dx"], a["dy"], a["rotation_degree"], element_name) ); } else if (element_type == "kicker") { auto a = detail::query_alignment(pp_element); @@ -370,7 +370,7 @@ namespace detail Kicker::UnitSystem::dimensionless : Kicker::UnitSystem::Tm; - m_lattice.emplace_back( Kicker(xkick, ykick, units, a["dx"], a["dy"], a["rotation_degree"]) ); + m_lattice.emplace_back( Kicker(xkick, ykick, units, a["dx"], a["dy"], a["rotation_degree"], element_name) ); } else if (element_type == "aperture") { auto a = detail::query_alignment(pp_element); @@ -386,7 +386,7 @@ namespace detail Aperture::Shape::rectangular : Aperture::Shape::elliptical; - m_lattice.emplace_back( Aperture(xmax, ymax, shape, a["dx"], a["dy"], a["rotation_degree"]) ); + m_lattice.emplace_back( Aperture(xmax, ymax, shape, 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/ReferenceParticle.H b/src/particles/ReferenceParticle.H index 7f1b7ae19..226025b74 100644 --- a/src/particles/ReferenceParticle.H +++ b/src/particles/ReferenceParticle.H @@ -66,7 +66,7 @@ namespace impactx using namespace amrex::literals; amrex::ParticleReal const ref_gamma = -pt; - amrex::ParticleReal const ref_beta = sqrt(1.0_prt - 1.0_prt/pow(ref_gamma,2)); + amrex::ParticleReal const ref_beta = std::sqrt(1.0_prt - 1.0_prt/pow(ref_gamma,2)); return ref_beta; } @@ -81,7 +81,7 @@ namespace impactx using namespace amrex::literals; amrex::ParticleReal const ref_gamma = -pt; - amrex::ParticleReal const ref_betagamma = sqrt(pow(ref_gamma, 2) - 1.0_prt); + amrex::ParticleReal const ref_betagamma = std::sqrt(std::pow(ref_gamma, 2) - 1.0_prt); return ref_betagamma; } @@ -118,7 +118,7 @@ namespace impactx if (pt != 0.0_prt) { pt = -kin_energy_MeV() / massE - 1.0_prt; - pz = sqrt(pow(pt, 2) - 1.0_prt); + pz = std::sqrt(std::pow(pt, 2) - 1.0_prt); } return *this; @@ -155,7 +155,7 @@ namespace impactx px = 0.0; py = 0.0; pt = -kin_energy / mass_MeV() - 1.0_prt; - pz = sqrt(pow(pt, 2) - 1.0_prt); + pz = std::sqrt(std::pow(pt, 2) - 1.0_prt); return *this; } @@ -171,7 +171,7 @@ namespace impactx using namespace amrex::literals; amrex::ParticleReal const ref_gamma = -pt; - amrex::ParticleReal const ref_betagamma = sqrt(pow(ref_gamma, 2) - 1.0_prt); + amrex::ParticleReal const ref_betagamma = std::sqrt(std::pow(ref_gamma, 2) - 1.0_prt); //amrex::ParticleReal const ref_rigidity = mass*ref_betagamma*(ablastr::constant::SI::c)/charge; //fails due to "charge" amrex::ParticleReal const ref_rigidity = mass*ref_betagamma*(ablastr::constant::SI::c)/(ablastr::constant::SI::q_e); return ref_rigidity; diff --git a/src/particles/distribution/Gaussian.H b/src/particles/distribution/Gaussian.H index d6baf9640..24397c0b0 100644 --- a/src/particles/distribution/Gaussian.H +++ b/src/particles/distribution/Gaussian.H @@ -100,34 +100,34 @@ namespace impactx::distribution u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - x = ln1*cos(2_prt*pi*u2); - px = ln1*sin(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + x = ln1 * std::cos(2_prt*pi*u2); + px = ln1 * std::sin(2_prt*pi*u2); u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - y = ln1*cos(2_prt*pi*u2); - py = ln1*sin(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + y = ln1 * std::cos(2_prt*pi*u2); + py = ln1 * std::sin(2_prt*pi*u2); u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - t = ln1*cos(2_prt*pi*u2); - pt = ln1*sin(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + t = ln1 * std::cos(2_prt*pi*u2); + pt = ln1 * std::sin(2_prt*pi*u2); // Transform to produce the desired second moments/correlations: - root = sqrt(1.0_prt-m_muxpx*m_muxpx); + root = std::sqrt(1.0_prt-m_muxpx*m_muxpx); a1 = m_lambdaX * x / root; a2 = m_lambdaPx * (-m_muxpx * x / root + px); x = a1; px = a2; - root = sqrt(1.0_prt-m_muypy*m_muypy); + root = std::sqrt(1.0_prt-m_muypy*m_muypy); a1 = m_lambdaY * y / root; a2 = m_lambdaPy * (-m_muypy * y / root + py); y = a1; py = a2; - root = sqrt(1.0_prt-m_mutpt*m_mutpt); + root = std::sqrt(1.0_prt-m_mutpt*m_mutpt); a1 = m_lambdaT * t / root; a2 = m_lambdaPt * (-m_mutpt * t / root + pt); t = a1; diff --git a/src/particles/distribution/KVdist.H b/src/particles/distribution/KVdist.H index 87e343399..3554013eb 100644 --- a/src/particles/distribution/KVdist.H +++ b/src/particles/distribution/KVdist.H @@ -101,27 +101,27 @@ namespace impactx::distribution v = amrex::Random(engine); phi = amrex::Random(engine); phi = 2_prt*pi*phi; - r = sqrt(v); - x = r*cos(phi); - y = r*sin(phi); + r = std::sqrt(v); + x = r * std::cos(phi); + y = r * std::sin(phi); // Sample and transform to define (px,py): beta = amrex::Random(engine); beta = 2_prt*pi*beta; - p = sqrt(1_prt-pow(r,2)); - px = p*cos(beta); - py = p*sin(beta); + p = std::sqrt(1_prt-pow(r,2)); + px = p * std::cos(beta); + py = p * std::sin(beta); // Sample and transform to define (t,pt): t = amrex::Random(engine); t = 2.0_prt*(t-0.5_prt); u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - pt = ln1*cos(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + pt = ln1 * std::cos(2_prt*pi*u2); // Scale to produce the identity covariance matrix: - amrex::ParticleReal const c = sqrt(3.0_prt); + amrex::ParticleReal const c = std::sqrt(3.0_prt); x = 2_prt*x; y = 2_prt*y; t = c*t; @@ -130,17 +130,17 @@ namespace impactx::distribution // pt = pt; // Transform to produce the desired second moments/correlations: - root = sqrt(1.0_prt-m_muxpx*m_muxpx); + root = std::sqrt(1.0_prt-m_muxpx*m_muxpx); a1 = m_lambdaX * x / root; a2 = m_lambdaPx * (-m_muxpx * x / root + px); x = a1; px = a2; - root = sqrt(1.0_prt-m_muypy*m_muypy); + root = std::sqrt(1.0_prt-m_muypy*m_muypy); a1 = m_lambdaY * y / root; a2 = m_lambdaPy * (-m_muypy * y / root + py); y = a1; py = a2; - root = sqrt(1.0_prt-m_mutpt*m_mutpt); + root = std::sqrt(1.0_prt-m_mutpt*m_mutpt); a1 = m_lambdaT * t / root; a2 = m_lambdaPt * (-m_mutpt * t / root + pt); t = a1; diff --git a/src/particles/distribution/Kurth4D.H b/src/particles/distribution/Kurth4D.H index cd254d2f9..d5b40e2d7 100644 --- a/src/particles/distribution/Kurth4D.H +++ b/src/particles/distribution/Kurth4D.H @@ -102,9 +102,9 @@ namespace impactx::distribution v = amrex::Random(engine); phi = amrex::Random(engine); phi = 2_prt*pi*phi; - r = sqrt(v); - x = r*cos(phi); - y = r*sin(phi); + r = std::sqrt(v); + x = r * std::cos(phi); + y = r * std::sin(phi); // Random samples used to define Lz: u = amrex::Random(engine); @@ -113,25 +113,25 @@ namespace impactx::distribution // Random samples used to define pr: alpha = amrex::Random(engine); alpha = pi*alpha; - pmax = 1.0_prt - pow((Lz/r),2) - pow(r,2) + pow(Lz,2); - pmax = sqrt(pmax); - pr = pmax*cos(alpha); + pmax = 1.0_prt - std::pow((Lz/r),2) - std::pow(r,2) + std::pow(Lz,2); + pmax = std::sqrt(pmax); + pr = pmax * std::cos(alpha); pphi = Lz/r; // Transformations used to obtain (px,py): - px = pr*cos(phi)-pphi*sin(phi); - py = pr*sin(phi)+pphi*cos(phi); + px = pr * std::cos(phi)-pphi * std::sin(phi); + py = pr * std::sin(phi)+pphi * std::cos(phi); // Sample and transform to define (t,pt): t = amrex::Random(engine); t = 2.0_prt*(t-0.5_prt); u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - pt = ln1*cos(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + pt = ln1 * std::cos(2_prt*pi*u2); // Scale to produce the identity covariance matrix: - amrex::ParticleReal const c = sqrt(3.0_prt); + amrex::ParticleReal const c = std::sqrt(3.0_prt); x = 2_prt*x; y = 2_prt*y; t = c*t; @@ -140,17 +140,17 @@ namespace impactx::distribution // pt = pt; // Transform to produce the desired second moments/correlations: - root = sqrt(1.0_prt-m_muxpx*m_muxpx); + root = std::sqrt(1.0_prt-m_muxpx*m_muxpx); a1 = m_lambdaX * x / root; a2 = m_lambdaPx * (-m_muxpx * x / root + px); x = a1; px = a2; - root = sqrt(1.0_prt-m_muypy*m_muypy); + root = std::sqrt(1.0_prt-m_muypy*m_muypy); a1 = m_lambdaY * y / root; a2 = m_lambdaPy * (-m_muypy * y / root + py); y = a1; py = a2; - root = sqrt(1.0_prt-m_mutpt*m_mutpt); + root = std::sqrt(1.0_prt-m_mutpt*m_mutpt); a1 = m_lambdaT * t / root; a2 = m_lambdaPt * (-m_mutpt * t / root + pt); t = a1; diff --git a/src/particles/distribution/Kurth6D.H b/src/particles/distribution/Kurth6D.H index e3d1b8c42..b0a1da425 100644 --- a/src/particles/distribution/Kurth6D.H +++ b/src/particles/distribution/Kurth6D.H @@ -104,40 +104,40 @@ namespace impactx::distribution v = amrex::Random(engine); costheta = amrex::Random(engine); costheta = 2_prt*(costheta-0.5_prt); - sintheta = sqrt(1_prt-pow(costheta,2)); + sintheta = std::sqrt(1_prt-pow(costheta,2)); phi = amrex::Random(engine); phi = 2_prt*pi*phi; // Transformations for (x,y,t): - r = pow(v,1_prt/3_prt); - x = r*sintheta*cos(phi); - y = r*sintheta*sin(phi); + r = std::pow(v,1_prt/3_prt); + x = r*sintheta * std::cos(phi); + y = r*sintheta * std::sin(phi); t = r*costheta; // Random samples used to define L: L = amrex::Random(engine); - L = r*sqrt(L); + L = r*std::sqrt(L); // Random samples used to define pr: alpha = amrex::Random(engine); alpha = pi*alpha; - pmax = 1_prt - pow(L/r,2) - pow(r,2) + pow(L,2); - pmax = sqrt(pmax); - pr = pmax*cos(alpha); + pmax = 1_prt - std::pow(L/r,2) - std::pow(r,2) + std::pow(L,2); + pmax = std::sqrt(pmax); + pr = pmax * std::cos(alpha); // Random samples used to define ptangent: beta = amrex::Random(engine); beta = 2_prt*pi*beta; - p1 = L/r*cos(beta); // This is phi component - p2 = L/r*sin(beta); // This is theta component + p1 = L/r * std::cos(beta); // This is phi component + p2 = L/r * std::sin(beta); // This is theta component // Transformation from spherical to Cartesian coord.: - px = pr*sintheta*cos(phi) + p2*costheta*cos(phi) - p1*sin(phi); - py = pr*sintheta*sin(phi) + p2*costheta*sin(phi) + p1*cos(phi); + px = pr*sintheta * std::cos(phi) + p2*costheta * std::cos(phi) - p1 * std::sin(phi); + py = pr*sintheta * std::sin(phi) + p2*costheta * std::sin(phi) + p1 * std::cos(phi); pt = pr*costheta - p2*sintheta; // Scale to produce the identity covariance matrix: - amrex::ParticleReal const c = sqrt(5.0_prt); + amrex::ParticleReal const c = std::sqrt(5.0_prt); x = c*x; y = c*y; t = c*t; @@ -146,17 +146,17 @@ namespace impactx::distribution pt = c*pt; // Transform to produce the desired second moments/correlations: - root = sqrt(1.0_prt-m_muxpx*m_muxpx); + root = std::sqrt(1.0_prt-m_muxpx*m_muxpx); a1 = m_lambdaX * x / root; a2 = m_lambdaPx * (-m_muxpx * x / root + px); x = a1; px = a2; - root = sqrt(1.0_prt-m_muypy*m_muypy); + root = std::sqrt(1.0_prt-m_muypy*m_muypy); a1 = m_lambdaY * y / root; a2 = m_lambdaPy * (-m_muypy * y / root + py); y = a1; py = a2; - root = sqrt(1.0_prt-m_mutpt*m_mutpt); + root = std::sqrt(1.0_prt-m_mutpt*m_mutpt); a1 = m_lambdaT * t / root; a2 = m_lambdaPt * (-m_mutpt * t / root + pt); t = a1; diff --git a/src/particles/distribution/Semigaussian.H b/src/particles/distribution/Semigaussian.H index 63d985657..f6c3deaa1 100644 --- a/src/particles/distribution/Semigaussian.H +++ b/src/particles/distribution/Semigaussian.H @@ -103,14 +103,14 @@ namespace impactx::distribution phi = amrex::Random(engine); phi = 2_prt*pi*phi; v = amrex::Random(engine); - r = sqrt(v); - x = r*cos(phi); - y = r*sin(phi); + r = std::sqrt(v); + x = r * std::cos(phi); + y = r * std::sin(phi); t = amrex::Random(engine); t = 2_prt*(t-0.5_prt); // Scale to produce the identity covariance matrix: - amrex::ParticleReal const c = sqrt(3.0_prt); + amrex::ParticleReal const c = std::sqrt(3.0_prt); x = 2_prt*x; y = 2_prt*y; t = c*t; @@ -119,27 +119,27 @@ namespace impactx::distribution u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - px = ln1*cos(2_prt*pi*u2); - py = ln1*sin(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + px = ln1 * std::cos(2_prt*pi*u2); + py = ln1 * std::sin(2_prt*pi*u2); u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - pt = ln1*cos(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + pt = ln1 * std::cos(2_prt*pi*u2); // Transform to produce the desired second moments/correlations: - root = sqrt(1.0_prt-m_muxpx*m_muxpx); + root = std::sqrt(1.0_prt-m_muxpx*m_muxpx); a1 = m_lambdaX * x / root; a2 = m_lambdaPx * (-m_muxpx * x / root + px); x = a1; px = a2; - root = sqrt(1.0_prt-m_muypy*m_muypy); + root = std::sqrt(1.0_prt-m_muypy*m_muypy); a1 = m_lambdaY * y / root; a2 = m_lambdaPy * (-m_muypy * y / root + py); y = a1; py = a2; - root = sqrt(1.0_prt-m_mutpt*m_mutpt); + root = std::sqrt(1.0_prt-m_mutpt*m_mutpt); a1 = m_lambdaT * t / root; a2 = m_lambdaPt * (-m_mutpt * t / root + pt); t = a1; diff --git a/src/particles/distribution/Thermal.H b/src/particles/distribution/Thermal.H index 63169332a..898f86a4a 100644 --- a/src/particles/distribution/Thermal.H +++ b/src/particles/distribution/Thermal.H @@ -97,7 +97,7 @@ namespace distribution amrex::ParticleReal q_e = refpart.charge_qe(); // Set space charge intensity - m_Cintensity = q_e*bunch_charge/(pow(bg,2)*Erest*ablastr::constant::SI::ep0); + m_Cintensity = q_e*bunch_charge/(std::pow(bg,2)*Erest*ablastr::constant::SI::ep0); // Set minimum and maximum radius amrex::ParticleReal r_scale = matched_scale_radius(); @@ -106,8 +106,8 @@ namespace distribution // amrex::PrintToFile("equilibrium_params.out") << r_scale << " " << data.Cintensity << "\n"; // Scale the parameters p1 and p2 - amrex::ParticleReal rt2pi = sqrt(2.0_prt*pi); - amrex::ParticleReal p_scale = pow(r_scale*rt2pi,-3); + amrex::ParticleReal rt2pi = std::sqrt(2.0_prt*pi); + amrex::ParticleReal p_scale = std::pow(r_scale*rt2pi,-3); m_p1 = m_p1*p_scale; m_p2 = m_p2*p_scale; @@ -161,8 +161,8 @@ namespace distribution amrex::ParticleReal k = m_k; amrex::ParticleReal kT = (1.0_prt - m_w) * m_T1 + m_w * m_T2; - amrex::ParticleReal a = m_Cintensity/(4.0_prt*pi*5.0_prt*sqrt(5.0_prt)); - amrex::ParticleReal rscale = sqrt(kT + pow(a*k,2.0/3.0))/k; + amrex::ParticleReal a = m_Cintensity/(4.0_prt*pi*5.0_prt*std::sqrt(5.0_prt)); + amrex::ParticleReal rscale = std::sqrt(kT + std::pow(a*k,2.0/3.0))/k; return rscale; } @@ -252,17 +252,17 @@ namespace distribution // Define intermediate quantities amrex::ParticleReal potential = 0.0_prt; - potential = pow(k*r,2.0)/2.0_prt + c1*phi1 + c2*phi2; - amrex::ParticleReal Pdensity1 = m_p1*exp(-potential/T1); - amrex::ParticleReal Pdensity2 = m_p2*exp(-potential/T2); + potential = std::pow(k*r,2.0)/2.0_prt + c1*phi1 + c2*phi2; + amrex::ParticleReal Pdensity1 = m_p1 * std::exp(-potential/T1); + amrex::ParticleReal Pdensity2 = m_p2 * std::exp(-potential/T2); // amrex::ParticleReal Pdensity_tot = (1.0_prt-w)*Pdensity1 + w*Pdensity2; // amrex::PrintToFile("Pdensity.out") << reval << " " << Pdensity_tot << "\n"; // Apply map to update f1 and f2: m_phi1 = phi1; m_phi2 = phi2; - m_f1 = f1 + tau*4.0_prt*pi*pow(r,2.0)*Pdensity1; - m_f2 = f2 + tau*4.0_prt*pi*pow(r,2.0)*Pdensity2; + m_f1 = f1 + tau*4.0_prt*pi * std::pow(r,2.0)*Pdensity1; + m_f2 = f2 + tau*4.0_prt*pi * std::pow(r,2.0)*Pdensity2; reval = r; } }; @@ -371,28 +371,28 @@ namespace distribution // Generate six standard normal random variables using Box-Muller: u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - g1 = ln1*cos(2_prt*pi*u2); - g2 = ln1*sin(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + g1 = ln1 * std::cos(2_prt*pi*u2); + g2 = ln1 * std::sin(2_prt*pi*u2); u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - g3 = ln1*cos(2_prt*pi*u2); - g4 = ln1*sin(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + g3 = ln1 * std::cos(2_prt*pi*u2); + g4 = ln1 * std::sin(2_prt*pi*u2); u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - g5 = ln1*cos(2_prt*pi*u2); - g6 = ln1*sin(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + g5 = ln1 * std::cos(2_prt*pi*u2); + g6 = ln1 * std::sin(2_prt*pi*u2); // Scale the last three variables to produce the momenta: amrex::ParticleReal kT = (uhalo > m_w) ? m_T1 : m_T2; // select core or halo value - px = sqrt(kT)*g4; - py = sqrt(kT)*g5; - pz = sqrt(kT)*g6; + px = std::sqrt(kT)*g4; + py = std::sqrt(kT)*g5; + pz = std::sqrt(kT)*g6; // Normalize the first three variables to produce uniform samples on the unit 3-sphere: - norm = sqrt(g1*g1+g2*g2+g3*g3); + norm = std::sqrt(g1*g1+g2*g2+g3*g3); g1 /= norm; g2 /= norm; g3 /= norm; diff --git a/src/particles/distribution/Triangle.H b/src/particles/distribution/Triangle.H index a1f40dc14..631dd5338 100644 --- a/src/particles/distribution/Triangle.H +++ b/src/particles/distribution/Triangle.H @@ -99,29 +99,29 @@ namespace impactx::distribution // Sample the t coordinate for a ramped triangular profile (unit // variance): u0 = amrex::Random(engine); - t = sqrt(2_prt)*(2_prt-3_prt*sqrt(u0)); + t = std::sqrt(2_prt)*(2_prt-3_prt*std::sqrt(u0)); // Generate five standard normal random variables using Box-Muller: u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - g1 = ln1*cos(2_prt*pi*u2); - g2 = ln1*sin(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + g1 = ln1 * std::cos(2_prt*pi*u2); + g2 = ln1 * std::sin(2_prt*pi*u2); u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - g3 = ln1*cos(2_prt*pi*u2); - g4 = ln1*sin(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + g3 = ln1 * std::cos(2_prt*pi*u2); + g4 = ln1 * std::sin(2_prt*pi*u2); u1 = amrex::Random(engine); u2 = amrex::Random(engine); - ln1 = sqrt(-2_prt*log(u1)); - g5 = ln1*cos(2_prt*pi*u2); + ln1 = std::sqrt(-2_prt*std::log(u1)); + g5 = ln1 * std::cos(2_prt*pi*u2); // Use one of these normal random variables for pt: pt = g5; // Normalize the rest to produce uniform samples on the unit sphere: - norm = sqrt(g1*g1+g2*g2+g3*g3+g4*g4); + norm = std::sqrt(g1*g1+g2*g2+g3*g3+g4*g4); g1 /= norm; g2 /= norm; g3 /= norm; @@ -130,24 +130,24 @@ namespace impactx::distribution // Scale to produce uniform samples in a 4D ball (unit variance): d = 4_prt; // unit ball dimension u1 = amrex::Random(engine); // uniform sample - u2 = sqrt(d+2_prt)*pow(u1,1_prt/d); + u2 = std::sqrt(d+2_prt) * std::pow(u1,1_prt/d); x = g1*u2; y = g2*u2; px = g3*u2; py = g4*u2; // Transform to produce the desired second moments/correlations: - root = sqrt(1.0_prt-m_muxpx*m_muxpx); + root = std::sqrt(1.0_prt-m_muxpx*m_muxpx); a1 = m_lambdaX * x / root; a2 = m_lambdaPx * (-m_muxpx * x / root + px); x = a1; px = a2; - root = sqrt(1.0_prt-m_muypy*m_muypy); + root = std::sqrt(1.0_prt-m_muypy*m_muypy); a1 = m_lambdaY * y / root; a2 = m_lambdaPy * (-m_muypy * y / root + py); y = a1; py = a2; - root = sqrt(1.0_prt-m_mutpt*m_mutpt); + root = std::sqrt(1.0_prt-m_mutpt*m_mutpt); a1 = m_lambdaT * t / root; a2 = m_lambdaPt * (-m_mutpt * t / root + pt); t = a1; diff --git a/src/particles/elements/All.H b/src/particles/elements/All.H index 6f7f72066..ba108c9fe 100644 --- a/src/particles/elements/All.H +++ b/src/particles/elements/All.H @@ -23,6 +23,7 @@ #include "ExactDrift.H" #include "ExactSbend.H" #include "Kicker.H" +#include "Marker.H" #include "Multipole.H" #include "Empty.H" #include "NonlinearLens.H" @@ -60,6 +61,7 @@ namespace impactx ExactDrift, ExactSbend, Kicker, + Marker, Multipole, NonlinearLens, Programmable, diff --git a/src/particles/elements/Aperture.H b/src/particles/elements/Aperture.H index 2f1e6e9eb..9c286870e 100644 --- a/src/particles/elements/Aperture.H +++ b/src/particles/elements/Aperture.H @@ -15,6 +15,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct Aperture - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::Alignment, public elements::NoFinalize @@ -33,12 +35,16 @@ namespace impactx static constexpr auto type = "Aperture"; using PType = ImpactXParticleContainer::ParticleType; + // TODO: make AMREX_ENUM and simplify @see shape_name implementation with it enum Shape { rectangular, elliptical }; + static std::string + shape_name (Shape const & shape); + /** A thin collimator element that applies a transverse aperture boundary. * Particles outside the boundary are considered lost. * @@ -48,6 +54,7 @@ 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 name a user defined and not necessarily unique name of the element */ Aperture ( amrex::ParticleReal xmax, @@ -55,9 +62,11 @@ namespace impactx Shape shape, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, - amrex::ParticleReal rotation_degree = 0 + amrex::ParticleReal rotation_degree = 0, + std::optional name = std::nullopt ) - : Alignment(dx, dy, rotation_degree), + : Named(name), + Alignment(dx, dy, rotation_degree), m_shape(shape), m_xmax(xmax), m_ymax(ymax) { } @@ -102,13 +111,13 @@ namespace impactx switch (m_shape) { case Shape::rectangular : // default - if (pow(u,2)>1 || pow(v,2) > 1_prt) { + if (std::pow(u,2)>1 || std::pow(v,2) > 1_prt) { amrex::ParticleIDWrapper{idcpu}.make_invalid(); } break; case Shape::elliptical : - if (pow(u,2)+pow(v,2) > 1_prt) { + if (std::pow(u,2) + std::pow(v,2) > 1_prt) { amrex::ParticleIDWrapper{idcpu}.make_invalid(); } break; diff --git a/src/particles/elements/Aperture.cpp b/src/particles/elements/Aperture.cpp new file mode 100644 index 000000000..c647bca7c --- /dev/null +++ b/src/particles/elements/Aperture.cpp @@ -0,0 +1,28 @@ +/* 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: Chad Mitchell, Axel Huebl + * License: BSD-3-Clause-LBNL + */ +#include "Aperture.H" + +#include +#include + + +std::string +impactx::Aperture::shape_name (Shape const & shape) +{ + switch (shape) + { + case Aperture::Shape::rectangular : // default + return "rectangular"; + case Aperture::Shape::elliptical : + return "elliptical"; + default: + throw std::runtime_error("Unknown shape"); + } +} diff --git a/src/particles/elements/Buncher.H b/src/particles/elements/Buncher.H index 1dc83d4ed..bccbdab6a 100644 --- a/src/particles/elements/Buncher.H +++ b/src/particles/elements/Buncher.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct Buncher - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::Alignment, public elements::NoFinalize @@ -40,15 +42,18 @@ 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 name a user defined and not necessarily unique name of the element */ Buncher ( amrex::ParticleReal V, amrex::ParticleReal k, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, - amrex::ParticleReal rotation_degree = 0 + amrex::ParticleReal rotation_degree = 0, + std::optional name = std::nullopt ) - : Alignment(dx, dy, rotation_degree), + : Named(name), + Alignment(dx, dy, rotation_degree), m_V(V), m_k(k) { } @@ -86,7 +91,7 @@ namespace impactx // access reference particle values to find (beta*gamma)^2 amrex::ParticleReal const pt_ref = refpart.pt; - amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; + amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt; // intialize output values of momenta amrex::ParticleReal pxout = px; diff --git a/src/particles/elements/CFbend.H b/src/particles/elements/CFbend.H index 2db863ce0..bd42851ac 100644 --- a/src/particles/elements/CFbend.H +++ b/src/particles/elements/CFbend.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -26,7 +27,8 @@ namespace impactx { struct CFbend - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -47,6 +49,7 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ CFbend ( amrex::ParticleReal ds, @@ -55,9 +58,11 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_rc(rc), m_k(k) { @@ -109,18 +114,18 @@ namespace impactx // access reference particle values to find beta*gamma^2 amrex::ParticleReal const pt_ref = refpart.pt; - amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; - amrex::ParticleReal const bet = sqrt(betgam2/(1.0_prt + betgam2)); + amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt; + amrex::ParticleReal const bet = std::sqrt(betgam2/(1.0_prt + betgam2)); // update horizontal and longitudinal phase space variables - amrex::ParticleReal const gx = m_k + pow(m_rc,-2); - amrex::ParticleReal const omegax = sqrt(std::abs(gx)); + amrex::ParticleReal const gx = m_k + std::pow(m_rc,-2); + amrex::ParticleReal const omegax = std::sqrt(std::abs(gx)); if(gx > 0.0) { // calculate expensive terms once auto const [sinx, cosx] = amrex::Math::sincos(omegax * slice_ds); amrex::ParticleReal const r56 = slice_ds/betgam2 - + (sinx - omegax*slice_ds)/(gx*omegax*pow(bet,2)*pow(m_rc,2)); + + (sinx - omegax*slice_ds)/(gx*omegax * std::pow(bet,2) * std::pow(m_rc,2)); // advance position and momentum (focusing) x = cosx*xout + sinx/omegax*px - (1.0_prt - cosx)/(gx*bet*m_rc)*pt; @@ -131,10 +136,10 @@ namespace impactx ptout = pt; } else { // calculate expensive terms once - amrex::ParticleReal const sinhx = sinh(omegax * slice_ds); - amrex::ParticleReal const coshx = cosh(omegax * slice_ds); + amrex::ParticleReal const sinhx = std::sinh(omegax * slice_ds); + amrex::ParticleReal const coshx = std::cosh(omegax * slice_ds); amrex::ParticleReal const r56 = slice_ds/betgam2 - + (sinhx - omegax*slice_ds)/(gx*omegax*pow(bet,2)*pow(m_rc,2)); + + (sinhx - omegax*slice_ds)/(gx*omegax * std::pow(bet,2) * std::pow(m_rc,2)); // advance position and momentum (defocusing) x = coshx*xout + sinhx/omegax*px - (1.0_prt - coshx)/(gx*bet*m_rc)*pt; @@ -147,7 +152,7 @@ namespace impactx // update vertical phase space variables amrex::ParticleReal const gy = -m_k; - amrex::ParticleReal const omegay = sqrt(std::abs(gy)); + amrex::ParticleReal const omegay = std::sqrt(std::abs(gy)); if(gy > 0.0) { // calculate expensive terms once @@ -159,8 +164,8 @@ namespace impactx } else { // calculate expensive terms once - amrex::ParticleReal const sinhy = sinh(omegay * slice_ds); - amrex::ParticleReal const coshy = cosh(omegay * slice_ds); + amrex::ParticleReal const sinhy = std::sinh(omegay * slice_ds); + amrex::ParticleReal const coshy = std::cosh(omegay * slice_ds); // advance position and momentum (defocusing) y = coshy*yout + sinhy/omegay*py; @@ -201,7 +206,7 @@ namespace impactx // assign intermediate parameter amrex::ParticleReal const theta = slice_ds/m_rc; - amrex::ParticleReal const B = sqrt(pow(pt,2)-1.0_prt)/m_rc; + amrex::ParticleReal const B = std::sqrt(std::pow(pt,2)-1.0_prt)/m_rc; // calculate expensive terms once auto const [sin_theta, cos_theta] = amrex::Math::sincos(theta); diff --git a/src/particles/elements/CMakeLists.txt b/src/particles/elements/CMakeLists.txt index c7acb5785..dceec99c3 100644 --- a/src/particles/elements/CMakeLists.txt +++ b/src/particles/elements/CMakeLists.txt @@ -1,5 +1,6 @@ target_sources(lib PRIVATE + Aperture.cpp Programmable.cpp ) diff --git a/src/particles/elements/ChrDrift.H b/src/particles/elements/ChrDrift.H index 35edd625a..e042bbff2 100644 --- a/src/particles/elements/ChrDrift.H +++ b/src/particles/elements/ChrDrift.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct ChrDrift - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -43,15 +45,18 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ ChrDrift ( amrex::ParticleReal ds, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree) { } @@ -106,7 +111,7 @@ namespace impactx // compute particle momentum deviation delta + 1 amrex::ParticleReal delta1; - delta1 = sqrt(1_prt - 2_prt*pt/bet + pow(pt,2)); + delta1 = std::sqrt(1_prt - 2_prt*pt/bet + std::pow(pt,2)); // advance transverse position and momentum (drift) x = xout + slice_ds * px / delta1; @@ -115,12 +120,12 @@ namespace impactx // pyout = py; // the corresponding symplectic update to t - amrex::ParticleReal term = 2_prt*pow(pt,2)+pow(px,2)+pow(py,2); - term = 2_prt - 4_prt*bet*pt + pow(bet,2)*term; - term = -2_prt + pow(gam,2)*term; + amrex::ParticleReal term = 2_prt * std::pow(pt,2) + std::pow(px,2) + std::pow(py,2); + term = 2_prt - 4_prt*bet*pt + std::pow(bet,2)*term; + term = -2_prt + std::pow(gam,2)*term; term = (-1_prt+bet*pt)*term; - term = term/(2_prt*pow(bet,3)*pow(gam,2)); - t = tout - slice_ds * (1_prt / bet + term / pow(delta1, 3)); + term = term/(2_prt * std::pow(bet,3) * std::pow(gam,2)); + t = tout - slice_ds * (1_prt / bet + term /std::pow(delta1, 3)); // ptout = pt; // assign updated momenta @@ -156,7 +161,7 @@ namespace impactx amrex::ParticleReal const slice_ds = m_ds / nslice(); // assign intermediate parameter - amrex::ParticleReal const step = slice_ds / sqrt(pow(pt,2)-1.0_prt); + amrex::ParticleReal const step = slice_ds /std::sqrt(std::pow(pt,2)-1.0_prt); // advance position and momentum (drift) refpart.x = x + step*px; diff --git a/src/particles/elements/ChrPlasmaLens.H b/src/particles/elements/ChrPlasmaLens.H index 0d95d7583..4a4dfbb3b 100644 --- a/src/particles/elements/ChrPlasmaLens.H +++ b/src/particles/elements/ChrPlasmaLens.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct ChrPlasmaLens - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -49,6 +51,7 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ ChrPlasmaLens ( amrex::ParticleReal ds, @@ -57,9 +60,11 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_k(k), m_unit(unit) { @@ -110,12 +115,12 @@ namespace impactx // compute particle momentum deviation delta + 1 amrex::ParticleReal delta1; - delta1 = sqrt(1_prt - 2_prt*pt/bet + pow(pt,2)); + delta1 = std::sqrt(1_prt - 2_prt*pt/bet + std::pow(pt,2)); amrex::ParticleReal const delta = delta1 - 1_prt; // compute phase advance per unit length in s (in rad/m) // chromatic dependence on delta is included - amrex::ParticleReal const omega = sqrt(std::abs(g)/delta1); + amrex::ParticleReal const omega = std::sqrt(std::abs(g)/delta1); // initialize output values amrex::ParticleReal xout = x; @@ -148,13 +153,13 @@ namespace impactx amrex::ParticleReal const t0 = t - term*slice_ds/delta1; amrex::ParticleReal const w = omega*delta1; - amrex::ParticleReal const term1 = -(pow(p2,2)-pow(q2,2)*pow(w,2))*sin(2_prt*slice_ds*omega); - amrex::ParticleReal const term2 = -(pow(p1,2)-pow(q1,2)*pow(w,2))*sin(2_prt*slice_ds*omega); - amrex::ParticleReal const term3 = -2_prt*q2*p2*w*cos(2_prt*slice_ds*omega); - amrex::ParticleReal const term4 = -2_prt*q1*p1*w*cos(2_prt*slice_ds*omega); + amrex::ParticleReal const term1 = -(std::pow(p2,2)-pow(q2,2) * std::pow(w,2)) * std::sin(2_prt*slice_ds*omega); + amrex::ParticleReal const term2 = -(std::pow(p1,2)-pow(q1,2) * std::pow(w,2)) * std::sin(2_prt*slice_ds*omega); + amrex::ParticleReal const term3 = -2_prt*q2*p2*w * std::cos(2_prt*slice_ds*omega); + amrex::ParticleReal const term4 = -2_prt*q1*p1*w * std::cos(2_prt*slice_ds*omega); amrex::ParticleReal const term5 = 2_prt*omega*(q1*p1*delta1 + q2*p2*delta1 - -(pow(p1,2)+pow(p2,2))*slice_ds - (pow(q1,2)+pow(q2,2))*pow(w,2)*slice_ds); - t = t0 + (-1_prt+bet*pt)/(8_prt*bet*pow(delta1,3)*omega) + -(std::pow(p1,2) + std::pow(p2,2))*slice_ds - (std::pow(q1,2) + std::pow(q2,2)) * std::pow(w,2)*slice_ds); + t = t0 + (-1_prt+bet*pt)/(8_prt*bet * std::pow(delta1,3)*omega) *(term1+term2+term3+term4+term5); // ptout = pt; @@ -194,7 +199,7 @@ namespace impactx amrex::ParticleReal const slice_ds = m_ds / nslice(); // assign intermediate parameter - amrex::ParticleReal const step = slice_ds / sqrt(pow(pt,2)-1.0_prt); + amrex::ParticleReal const step = slice_ds /std::sqrt(std::pow(pt,2)-1.0_prt); // advance position and momentum (straight element) refpart.x = x + step*px; diff --git a/src/particles/elements/ChrQuad.H b/src/particles/elements/ChrQuad.H index 2c86cc809..7672fc3a9 100644 --- a/src/particles/elements/ChrQuad.H +++ b/src/particles/elements/ChrQuad.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -26,7 +27,8 @@ namespace impactx { struct ChrQuad - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -52,6 +54,7 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ ChrQuad ( amrex::ParticleReal ds, @@ -60,9 +63,11 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_k(k), m_unit(unit) { @@ -118,12 +123,12 @@ namespace impactx // compute particle momentum deviation delta + 1 amrex::ParticleReal delta1; - delta1 = sqrt(1_prt - 2_prt*pt/bet + pow(pt,2)); + delta1 = std::sqrt(1_prt - 2_prt*pt/bet + std::pow(pt,2)); amrex::ParticleReal const delta = delta1 - 1_prt; // compute phase advance per unit length in s (in rad/m) // chromatic dependence on delta is included - amrex::ParticleReal const omega = sqrt(std::abs(g)/delta1); + amrex::ParticleReal const omega = std::sqrt(std::abs(g)/delta1); // intialize output values of momenta amrex::ParticleReal pxout = px; @@ -138,23 +143,23 @@ namespace impactx if(g > 0.0) { // advance transverse position and momentum (focusing quad) - x = cos(omega*slice_ds) * xout + - sin(omega*slice_ds)/(omega*delta1)*px; - pxout = -omega * delta1 * sin(omega*slice_ds) * xout + cos(omega * slice_ds) * px; + x = std::cos(omega*slice_ds) * xout + + std::sin(omega*slice_ds)/(omega*delta1)*px; + pxout = -omega * delta1 *std::sin(omega*slice_ds) * xout + std::cos(omega * slice_ds) * px; - y = cosh(omega*slice_ds) * yout + - sinh(omega*slice_ds)/(omega*delta1)*py; - pyout = omega * delta1 * sinh(omega*slice_ds) * yout + cosh(omega * slice_ds) * py; + y = std::cosh(omega*slice_ds) * yout + + std::sinh(omega*slice_ds)/(omega*delta1)*py; + pyout = omega * delta1 * std::sinh(omega*slice_ds) * yout + std::cosh(omega * slice_ds) * py; } else { // advance transverse position and momentum (defocusing quad) - x = cosh(omega*slice_ds) * xout + - sinh(omega*slice_ds)/(omega*delta1)*px; - pxout = omega * delta1 * sinh(omega*slice_ds) * xout + cosh(omega * slice_ds) * px; + x = std::cosh(omega*slice_ds) * xout + + std::sinh(omega*slice_ds)/(omega*delta1)*px; + pxout = omega * delta1 * std::sinh(omega*slice_ds) * xout + std::cosh(omega * slice_ds) * px; - y = cos(omega*slice_ds) * yout + - sin(omega*slice_ds)/(omega*delta1)*py; - pyout = -omega * delta1 * sin(omega*slice_ds) * yout + cos(omega * slice_ds) * py; + y = std::cos(omega*slice_ds) * yout + + std::sin(omega*slice_ds)/(omega*delta1)*py; + pyout = -omega * delta1 *std::sin(omega*slice_ds) * yout + std::cos(omega * slice_ds) * py; q1 = yout; q2 = xout; @@ -169,13 +174,13 @@ namespace impactx amrex::ParticleReal const t0 = tout - term * slice_ds / delta1; amrex::ParticleReal const w = omega*delta1; - amrex::ParticleReal const term1 = -(pow(p2,2)+pow(q2,2)*pow(w,2))*sinh(2_prt*slice_ds*omega); - amrex::ParticleReal const term2 = -(pow(p1,2)-pow(q1,2)*pow(w,2))*sin(2_prt*slice_ds*omega); - amrex::ParticleReal const term3 = -2_prt*q2*p2*w*cosh(2_prt*slice_ds*omega); - amrex::ParticleReal const term4 = -2_prt*q1*p1*w*cos(2_prt*slice_ds*omega); + amrex::ParticleReal const term1 = -(std::pow(p2,2) + std::pow(q2,2) * std::pow(w,2))*std::sinh(2_prt*slice_ds*omega); + amrex::ParticleReal const term2 = -(std::pow(p1,2)-pow(q1,2) * std::pow(w,2)) * std::sin(2_prt*slice_ds*omega); + amrex::ParticleReal const term3 = -2_prt*q2*p2*w*std::cosh(2_prt*slice_ds*omega); + amrex::ParticleReal const term4 = -2_prt*q1*p1*w * std::cos(2_prt*slice_ds*omega); amrex::ParticleReal const term5 = 2_prt*omega*(q1*p1*delta1 + q2*p2*delta1 - -(pow(p1,2)+pow(p2,2))*slice_ds - (pow(q1,2)-pow(q2,2))*pow(w,2)*slice_ds); - t = t0 + (-1_prt+bet*pt)/(8_prt*bet*pow(delta1,3)*omega) + -(std::pow(p1,2) + std::pow(p2,2))*slice_ds - (std::pow(q1,2)-pow(q2,2)) * std::pow(w,2)*slice_ds); + t = t0 + (-1_prt+bet*pt)/(8_prt*bet * std::pow(delta1,3)*omega) *(term1+term2+term3+term4+term5); // ptout = pt; @@ -213,7 +218,7 @@ namespace impactx amrex::ParticleReal const slice_ds = m_ds / nslice(); // assign intermediate parameter - amrex::ParticleReal const step = slice_ds / sqrt(pow(pt,2)-1.0_prt); + amrex::ParticleReal const step = slice_ds /std::sqrt(std::pow(pt,2)-1.0_prt); // advance position and momentum (straight element) refpart.x = x + step*px; diff --git a/src/particles/elements/ChrUniformAcc.H b/src/particles/elements/ChrUniformAcc.H index 465b480c4..9cb1087ce 100644 --- a/src/particles/elements/ChrUniformAcc.H +++ b/src/particles/elements/ChrUniformAcc.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct ChrAcc - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -47,6 +49,7 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ ChrAcc ( amrex::ParticleReal ds, @@ -55,9 +58,11 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_ez(ez), m_bz(bz) { @@ -100,8 +105,8 @@ namespace impactx // access reference particle values (final, initial): amrex::ParticleReal const ptf_ref = refpart.pt; amrex::ParticleReal const pti_ref = ptf_ref + m_ez*slice_ds; - amrex::ParticleReal const bgf = sqrt(pow(ptf_ref, 2) - 1.0_prt); - amrex::ParticleReal const bgi = sqrt(pow(pti_ref, 2) - 1.0_prt); + amrex::ParticleReal const bgf = std::sqrt(std::pow(ptf_ref, 2) - 1.0_prt); + amrex::ParticleReal const bgi = std::sqrt(std::pow(pti_ref, 2) - 1.0_prt); // initial conversion from static to dynamic units: px = px*bgi; @@ -111,17 +116,17 @@ namespace impactx // compute intermediate quantities related to acceleration amrex::ParticleReal const pti_tot = pti_ref + pt; amrex::ParticleReal const ptf_tot = ptf_ref + pt; - amrex::ParticleReal const pzi_tot = sqrt(pow(pti_tot,2)-1_prt); - amrex::ParticleReal const pzf_tot = sqrt(pow(ptf_tot,2)-1_prt); - amrex::ParticleReal const pzi_ref = sqrt(pow(pti_ref,2)-1_prt); - amrex::ParticleReal const pzf_ref = sqrt(pow(ptf_ref,2)-1_prt); + amrex::ParticleReal const pzi_tot = std::sqrt(std::pow(pti_tot,2)-1_prt); + amrex::ParticleReal const pzf_tot = std::sqrt(std::pow(ptf_tot,2)-1_prt); + amrex::ParticleReal const pzi_ref = std::sqrt(std::pow(pti_ref,2)-1_prt); + amrex::ParticleReal const pzf_ref = std::sqrt(std::pow(ptf_ref,2)-1_prt); amrex::ParticleReal const numer = -ptf_tot + pzf_tot; amrex::ParticleReal const denom = -pti_tot + pzi_tot; // compute focusing constant (1/m) and rotation angle (in rad) amrex::ParticleReal const alpha = m_bz/2.0_prt; - amrex::ParticleReal const theta = alpha/m_ez*log(numer/denom); + amrex::ParticleReal const theta = alpha/m_ez*std::log(numer/denom); // intialize output values amrex::ParticleReal xout = x; @@ -132,15 +137,15 @@ namespace impactx amrex::ParticleReal ptout = pt; // advance positions and momenta using map for focusing - xout = cos(theta)*x + sin(theta)/alpha*px; - pxout = -alpha*sin(theta)*x + cos(theta)*px; + xout = std::cos(theta)*x + std::sin(theta)/alpha*px; + pxout = -alpha * std::sin(theta)*x + std::cos(theta)*px; - yout = cos(theta)*y + sin(theta)/alpha*py; - pyout = -alpha*sin(theta)*y + cos(theta)*py; + yout = std::cos(theta)*y + std::sin(theta)/alpha*py; + pyout = -alpha * std::sin(theta)*y + std::cos(theta)*py; // the correct symplectic update for t tout = t + (pzf_tot - pzf_ref - pzi_tot + pzi_ref)/m_ez; - tout = tout + (1_prt/pzi_tot - 1_prt/pzf_tot)*(pow(py-alpha*x,2)+pow(px+alpha*y,2))/(2_prt*m_ez); + tout = tout + (1_prt/pzi_tot - 1_prt/pzf_tot)*(std::pow(py-alpha*x,2) + std::pow(px+alpha*y,2))/(2_prt*m_ez); ptout = pt; // assign intermediate momenta @@ -149,11 +154,11 @@ namespace impactx pt = ptout; // advance positions and momenta using map for rotation - x = cos(theta)*xout + sin(theta)*yout; - pxout = cos(theta)*px + sin(theta)*py; + x = std::cos(theta)*xout + std::sin(theta)*yout; + pxout = std::cos(theta)*px + std::sin(theta)*py; - y = -sin(theta)*xout + cos(theta)*yout; - pyout = -sin(theta)*px + cos(theta)*py; + y = -std::sin(theta)*xout + std::cos(theta)*yout; + pyout = -std::sin(theta)*px + std::cos(theta)*py; t = tout; ptout = pt; @@ -196,14 +201,14 @@ namespace impactx amrex::ParticleReal const slice_ds = m_ds / nslice(); // compute intial value of beta*gamma - amrex::ParticleReal const bgi = sqrt(pow(pt, 2) - 1.0_prt); + amrex::ParticleReal const bgi = std::sqrt(std::pow(pt, 2) - 1.0_prt); // advance pt (uniform acceleration) refpart.pt = pt - m_ez*slice_ds; // compute final value of beta*gamma amrex::ParticleReal const ptf = refpart.pt; - amrex::ParticleReal const bgf = sqrt(pow(ptf, 2) - 1.0_prt); + amrex::ParticleReal const bgf = std::sqrt(std::pow(ptf, 2) - 1.0_prt); // update t refpart.t = t + (bgf - bgi)/m_ez; diff --git a/src/particles/elements/ConstF.H b/src/particles/elements/ConstF.H index ae1009e08..a1b29c676 100644 --- a/src/particles/elements/ConstF.H +++ b/src/particles/elements/ConstF.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct ConstF - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -43,6 +45,7 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ ConstF ( amrex::ParticleReal ds, @@ -52,9 +55,11 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_kx(kx), m_ky(ky), m_kt(kt) { @@ -92,7 +97,7 @@ namespace impactx // access reference particle values to find beta*gamma^2 amrex::ParticleReal const pt_ref = refpart.pt; - amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; + amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt; // intialize output values amrex::ParticleReal xout = x; @@ -106,14 +111,14 @@ namespace impactx amrex::ParticleReal const slice_ds = m_ds / nslice(); // advance position and momentum - xout = cos(m_kx*slice_ds)*x + sin(m_kx*slice_ds)/m_kx*px; - pxout = -m_kx*sin(m_kx*slice_ds)*x + cos(m_kx*slice_ds)*px; + xout = std::cos(m_kx*slice_ds)*x + std::sin(m_kx*slice_ds)/m_kx*px; + pxout = -m_kx * std::sin(m_kx*slice_ds)*x + std::cos(m_kx*slice_ds)*px; - yout = cos(m_ky*slice_ds)*y + sin(m_ky*slice_ds)/m_ky*py; - pyout = -m_ky*sin(m_ky*slice_ds)*y + cos(m_ky*slice_ds)*py; + yout = std::cos(m_ky*slice_ds)*y + std::sin(m_ky*slice_ds)/m_ky*py; + pyout = -m_ky * std::sin(m_ky*slice_ds)*y + std::cos(m_ky*slice_ds)*py; - tout = cos(m_kt*slice_ds)*t + sin(m_kt*slice_ds)/(betgam2*m_kt)*pt; - ptout = -(m_kt*betgam2)*sin(m_kt*slice_ds)*t + cos(m_kt*slice_ds)*pt; + tout = std::cos(m_kt*slice_ds)*t + std::sin(m_kt*slice_ds)/(betgam2*m_kt)*pt; + ptout = -(m_kt*betgam2) * std::sin(m_kt*slice_ds)*t + std::cos(m_kt*slice_ds)*pt; // assign updated values x = xout; @@ -151,7 +156,7 @@ namespace impactx amrex::ParticleReal const slice_ds = m_ds / nslice(); // assign intermediate parameter - amrex::ParticleReal const step = slice_ds / sqrt(pow(pt, 2)-1.0_prt); + amrex::ParticleReal const step = slice_ds /std::sqrt(std::pow(pt, 2)-1.0_prt); // advance position and momentum (straight element) refpart.x = x + step*px; diff --git a/src/particles/elements/DipEdge.H b/src/particles/elements/DipEdge.H index 15dba97bf..e05ab0dbf 100644 --- a/src/particles/elements/DipEdge.H +++ b/src/particles/elements/DipEdge.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct DipEdge - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::Alignment, public elements::NoFinalize @@ -49,6 +51,7 @@ 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 name a user defined and not necessarily unique name of the element */ DipEdge ( amrex::ParticleReal psi, @@ -57,9 +60,11 @@ namespace impactx amrex::ParticleReal K2, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, - amrex::ParticleReal rotation_degree = 0 + amrex::ParticleReal rotation_degree = 0, + std::optional name = std::nullopt ) - : Alignment(dx, dy, rotation_degree), + : Named(name), + Alignment(dx, dy, rotation_degree), m_psi(psi), m_rc(rc), m_g(g), m_K2(K2) { } @@ -96,13 +101,13 @@ namespace impactx shift_in(x, y, px, py); // edge focusing matrix elements (zero gap) - amrex::ParticleReal const R21 = tan(m_psi)/m_rc; + amrex::ParticleReal const R21 = std::tan(m_psi)/m_rc; amrex::ParticleReal R43 = -R21; amrex::ParticleReal vf = 0; // first-order effect of nonzero gap - vf = (1.0_prt + pow(sin(m_psi),2))/(pow(cos(m_psi),3)); - vf *= m_g * m_K2/(pow(m_rc,2)); + vf = (1.0_prt + std::pow(sin(m_psi),2))/(std::pow(cos(m_psi),3)); + vf *= m_g * m_K2/(std::pow(m_rc,2)); R43 += vf; // apply edge focusing diff --git a/src/particles/elements/Drift.H b/src/particles/elements/Drift.H index c04c6d230..fcb4ff6f8 100644 --- a/src/particles/elements/Drift.H +++ b/src/particles/elements/Drift.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct Drift - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -40,15 +42,18 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ Drift ( amrex::ParticleReal ds, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree) { } @@ -97,7 +102,7 @@ namespace impactx // access reference particle values to find beta*gamma^2 amrex::ParticleReal const pt_ref = refpart.pt; - amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; + amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt; // advance position and momentum (drift) xout = x + slice_ds * px; @@ -143,7 +148,7 @@ namespace impactx amrex::ParticleReal const slice_ds = m_ds / nslice(); // assign intermediate parameter - amrex::ParticleReal const step = slice_ds / sqrt(pow(pt,2)-1.0_prt); + amrex::ParticleReal const step = slice_ds /std::sqrt(std::pow(pt,2)-1.0_prt); // advance position and momentum (drift) refpart.x = x + step*px; diff --git a/src/particles/elements/Empty.H b/src/particles/elements/Empty.H index e0fd61b43..cf0dba130 100644 --- a/src/particles/elements/Empty.H +++ b/src/particles/elements/Empty.H @@ -12,6 +12,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -35,8 +36,8 @@ namespace impactx /** Push all particles - nothing to do here */ void operator() ( - ImpactXParticleContainer & /* pc */, - int /* step */ + ImpactXParticleContainer & /* pc */, + int /* step */ ) { // nothing to do } @@ -62,14 +63,14 @@ namespace impactx */ AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void operator() ( - [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT x, - [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT y, - [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT t, - [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT px, - [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT py, - [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT pt, - [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, - [[maybe_unused]] RefPart const & refpart + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT x, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT y, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT t, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT px, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT py, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT pt, + [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + [[maybe_unused]] RefPart const & refpart ) const { // nothing to do diff --git a/src/particles/elements/ExactDrift.H b/src/particles/elements/ExactDrift.H index cf10c12b8..2d976c300 100644 --- a/src/particles/elements/ExactDrift.H +++ b/src/particles/elements/ExactDrift.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct ExactDrift - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -40,15 +42,18 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ ExactDrift ( amrex::ParticleReal ds, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree) { } @@ -103,8 +108,8 @@ namespace impactx amrex::ParticleReal const betgam = refpart.beta_gamma(); // compute the radical in the denominator (= pz): - amrex::ParticleReal const pzden = sqrt(pow(pt-1_prt/bet,2) - - 1_prt/pow(betgam,2) - pow(px,2) - pow(py,2)); + amrex::ParticleReal const pzden = std::sqrt(std::pow(pt-1_prt/bet,2) - + 1_prt / std::pow(betgam,2) - std::pow(px,2) - std::pow(py,2)); // advance position and momentum (exact drift) x = xout + slice_ds * px / pzden; @@ -147,7 +152,7 @@ namespace impactx amrex::ParticleReal const slice_ds = m_ds / nslice(); // assign intermediate parameter - amrex::ParticleReal const step = slice_ds / sqrt(pow(pt,2)-1.0_prt); + amrex::ParticleReal const step = slice_ds /std::sqrt(std::pow(pt,2)-1.0_prt); // advance position and momentum (drift) refpart.x = x + step*px; diff --git a/src/particles/elements/ExactSbend.H b/src/particles/elements/ExactSbend.H index dbef6bc58..f34cac473 100644 --- a/src/particles/elements/ExactSbend.H +++ b/src/particles/elements/ExactSbend.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -27,7 +28,8 @@ namespace impactx { struct ExactSbend - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -55,6 +57,7 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ ExactSbend ( amrex::ParticleReal ds, @@ -63,9 +66,11 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_phi(phi * degree2rad), m_B(B) { @@ -131,8 +136,8 @@ namespace impactx amrex::ParticleReal ptout = pt; // assign intermediate quantities - amrex::ParticleReal const pperp = sqrt(pow(pt,2)-2.0_prt/bet*pt-pow(py,2)+1.0_prt); - amrex::ParticleReal const pzi = sqrt(pow(pperp,2)-pow(px,2)); + amrex::ParticleReal const pperp = std::sqrt(std::pow(pt,2)-2.0_prt/bet*pt-pow(py,2)+1.0_prt); + amrex::ParticleReal const pzi = std::sqrt(std::pow(pperp,2) - std::pow(px,2)); amrex::ParticleReal const rho = rc + xout; auto const [sin_phi, cos_phi] = amrex::Math::sincos(slice_phi); @@ -142,8 +147,8 @@ namespace impactx ptout = pt; // angle of momentum rotation - amrex::ParticleReal const pzf = sqrt(pow(pperp,2)-pow(pxout,2)); - amrex::ParticleReal const theta = slice_phi + asin(px/pperp) - asin(pxout/pperp); + amrex::ParticleReal const pzf = std::sqrt(std::pow(pperp,2)-pow(pxout,2)); + amrex::ParticleReal const theta = slice_phi + std::asin(px/pperp) - std::asin(pxout/pperp); // update position coordinates x = -rc + rho*cos_phi + rc*(pzf + px*sin_phi - pzi*cos_phi); diff --git a/src/particles/elements/Kicker.H b/src/particles/elements/Kicker.H index fd4090a82..3150900ab 100644 --- a/src/particles/elements/Kicker.H +++ b/src/particles/elements/Kicker.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct Kicker - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::Alignment, public elements::NoFinalize @@ -48,6 +50,7 @@ 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 name a user defined and not necessarily unique name of the element */ Kicker ( amrex::ParticleReal xkick, @@ -55,9 +58,11 @@ namespace impactx UnitSystem unit, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, - amrex::ParticleReal rotation_degree = 0 + amrex::ParticleReal rotation_degree = 0, + std::optional name = std::nullopt ) - : Alignment(dx, dy, rotation_degree), + : Named(name), + Alignment(dx, dy, rotation_degree), m_xkick(xkick), m_ykick(ykick), m_unit(unit) { } diff --git a/src/particles/elements/Marker.H b/src/particles/elements/Marker.H new file mode 100644 index 000000000..46eff72a4 --- /dev/null +++ b/src/particles/elements/Marker.H @@ -0,0 +1,89 @@ +/* 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_ELEMENT_MARKER_H +#define IMPACTX_ELEMENT_MARKER_H + +#include "particles/ImpactXParticleContainer.H" +#include "mixin/thin.H" +#include "mixin/named.H" +#include "mixin/nofinalize.H" + +#include +#include + + +namespace impactx +{ + struct Marker + : public elements::Named, + public elements::Thin, + public elements::NoFinalize + { + static constexpr auto type = "Marker"; + using PType = ImpactXParticleContainer::ParticleType; + + /** This named element does nothing. + * + * @param name a user defined and not necessarily unique name of the element + */ + Marker (std::string name) + : Named(name) + { + } + + /** Push all particles - nothing to do here */ + void operator() ( + ImpactXParticleContainer & /* pc */, + int /* step */ + ) { + // nothing to do + } + + /** Push all particles - nothing to do here */ + void operator() ( + ImpactXParticleContainer::iterator & /* pti */, + RefPart & AMREX_RESTRICT /* ref_part */ + ) { + // nothing to do + } + + /** Does nothing to a particle. + * + * @param x particle position in x + * @param y particle position in y + * @param t particle position in t + * @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 refpart reference particle + */ + AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE + void operator() ( + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT x, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT y, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT t, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT px, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT py, + [[maybe_unused]] amrex::ParticleReal & AMREX_RESTRICT pt, + [[maybe_unused]] uint64_t & AMREX_RESTRICT idcpu, + [[maybe_unused]] RefPart const & refpart + ) const + { + // nothing to do + } + + /** This pushes the reference particle. */ + using Thin::operator(); + }; + +} // namespace impactx + +#endif // IMPACTX_ELEMENT_MARKER_H diff --git a/src/particles/elements/Multipole.H b/src/particles/elements/Multipole.H index 04791d482..6f4814a2c 100644 --- a/src/particles/elements/Multipole.H +++ b/src/particles/elements/Multipole.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct Multipole - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::Alignment, public elements::NoFinalize @@ -41,6 +43,7 @@ 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 name a user defined and not necessarily unique name of the element */ Multipole ( int multipole, @@ -48,9 +51,11 @@ namespace impactx amrex::ParticleReal K_skew, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, - amrex::ParticleReal rotation_degree = 0 + amrex::ParticleReal rotation_degree = 0, + std::optional name = std::nullopt ) - : Alignment(dx, dy, rotation_degree), + : Named(name), + Alignment(dx, dy, rotation_degree), m_multipole(multipole), m_Kn(K_normal), m_Ks(K_skew) { // compute factorial of multipole index @@ -98,7 +103,7 @@ namespace impactx // access reference particle values to find (beta*gamma)^2 //amrex::ParticleReal const pt_ref = refpart.pt; - //amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; + //amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt; // intialize output values amrex::ParticleReal xout = x; diff --git a/src/particles/elements/NonlinearLens.H b/src/particles/elements/NonlinearLens.H index 93940b067..016d6123a 100644 --- a/src/particles/elements/NonlinearLens.H +++ b/src/particles/elements/NonlinearLens.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct NonlinearLens - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::Alignment, public elements::NoFinalize @@ -45,15 +47,18 @@ 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 name a user defined and not necessarily unique name of the element */ NonlinearLens ( amrex::ParticleReal knll, amrex::ParticleReal cnll, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, - amrex::ParticleReal rotation_degree = 0 + amrex::ParticleReal rotation_degree = 0, + std::optional name = std::nullopt ) - : Alignment(dx, dy, rotation_degree), + : Named(name), + Alignment(dx, dy, rotation_degree), m_knll(knll), m_cnll(cnll) { } @@ -95,7 +100,7 @@ namespace impactx // access reference particle values to find (beta*gamma)^2 //amrex::ParticleReal const pt_ref = refpart.pt; - //amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; + //amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt; // intialize output values amrex::ParticleReal xout = x; @@ -117,12 +122,12 @@ namespace impactx croot = amrex::sqrt(croot); // compute carcsin = arcsin(zeta) - Complex carcsin = im1*zeta + croot; - carcsin = -im1*amrex::log(carcsin); + Complex carcsin = im1 * zeta + croot; + carcsin = -im1 * amrex::log(carcsin); // compute complex function F'(zeta) - Complex dF = zeta/amrex::pow(croot, 2); - dF = dF + carcsin/amrex::pow(croot,3); + Complex dF = zeta / amrex::pow(croot, 2); + dF = dF + carcsin / amrex::pow(croot, 3); // compute momentum kick amrex::ParticleReal const kick = -m_knll/m_cnll; diff --git a/src/particles/elements/PRot.H b/src/particles/elements/PRot.H index ed21e74be..cbd43118c 100644 --- a/src/particles/elements/PRot.H +++ b/src/particles/elements/PRot.H @@ -13,6 +13,7 @@ #include "particles/ImpactXParticleContainer.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -27,7 +28,8 @@ namespace impactx { struct PRot - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::NoFinalize { @@ -43,12 +45,16 @@ namespace impactx * * @param phi_in Initial angle of reference trajectory w/r/t z (degrees) * @param phi_out Final angle of reference trajectory w/r/t/ z (degrees) + * @param name a user defined and not necessarily unique name of the element */ PRot ( amrex::ParticleReal phi_in, - amrex::ParticleReal phi_out + amrex::ParticleReal phi_out, + std::optional name = std::nullopt ) - : m_phi_in(phi_in * degree2rad), m_phi_out(phi_out * degree2rad) + : Named(name), + m_phi_in(phi_in * degree2rad), + m_phi_out(phi_out * degree2rad) { } @@ -97,8 +103,8 @@ namespace impactx auto const [sin_theta, cos_theta] = amrex::Math::sincos(theta); auto const [sin_phi_in, cos_phi_in] = amrex::Math::sincos(m_phi_in); - amrex::ParticleReal const pz = sqrt(1.0_prt - 2.0_prt*pt/beta - + pow(pt,2) - pow(py,2) - pow(px + sin_phi_in,2)); + amrex::ParticleReal const pz = std::sqrt(1.0_prt - 2.0_prt*pt/beta + + std::pow(pt,2) - std::pow(py,2) - std::pow(px + sin_phi_in,2)); amrex::ParticleReal const pzf = pz*cos_theta - (px + sin_phi_in)*sin_theta; // advance position and momentum diff --git a/src/particles/elements/Programmable.H b/src/particles/elements/Programmable.H index e679ccb6e..31e8b5fc3 100644 --- a/src/particles/elements/Programmable.H +++ b/src/particles/elements/Programmable.H @@ -10,8 +10,9 @@ #ifndef IMPACTX_ELEMENTS_PROGRAMMABLE_H #define IMPACTX_ELEMENTS_PROGRAMMABLE_H -#include "mixin/thick.H" #include "particles/ImpactXParticleContainer.H" +#include "mixin/named.H" +#include "mixin/thick.H" #include #include @@ -22,14 +23,23 @@ namespace impactx { struct Programmable + : public elements::Named { static constexpr auto type = "Programmable"; using PType = ImpactXParticleContainer::ParticleType; /** This element can be programmed + * + * @param ds Segment length 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 */ - Programmable (amrex::ParticleReal ds=0.0, int nslice=1) - : m_ds(ds), m_nslice(nslice) + Programmable ( + amrex::ParticleReal ds=0.0, + int nslice=1, + std::optional name = std::nullopt + ) + : Named(name), m_ds(ds), m_nslice(nslice) {} /** Push all particles relative to the reference particle diff --git a/src/particles/elements/Quad.H b/src/particles/elements/Quad.H index d97121ebe..b4178048b 100644 --- a/src/particles/elements/Quad.H +++ b/src/particles/elements/Quad.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct Quad - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -44,6 +46,7 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ Quad ( amrex::ParticleReal ds, @@ -51,9 +54,11 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_k(k) { diff --git a/src/particles/elements/RFCavity.H b/src/particles/elements/RFCavity.H index 6db8c9a12..e4aae613e 100644 --- a/src/particles/elements/RFCavity.H +++ b/src/particles/elements/RFCavity.H @@ -14,6 +14,7 @@ #include "particles/integrators/Integrators.H" #include "mixin/alignment.H" #include "mixin/beamoptic.H" +#include "mixin/named.H" #include "mixin/thick.H" #include @@ -102,7 +103,8 @@ namespace RFCavityData } // namespace RFCavityData struct RFCavity - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment { @@ -123,6 +125,7 @@ namespace RFCavityData * @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 a user defined and not necessarily unique name of the element */ RFCavity ( amrex::ParticleReal ds, @@ -135,9 +138,11 @@ namespace RFCavityData amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, int mapsteps = 1, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_escale(escale), m_freq(freq), m_phase(phase), m_mapsteps(mapsteps) { @@ -282,7 +287,7 @@ namespace RFCavityData amrex::ParticleReal const slice_ds = m_ds / nslice(); // compute intial value of beta*gamma - amrex::ParticleReal const bgi = sqrt(pow(pt, 2) - 1.0_prt); + amrex::ParticleReal const bgi = std::sqrt(std::pow(pt, 2) - 1.0_prt); // call integrator to advance (t,pt) amrex::ParticleReal const zin = s - sedge; @@ -298,7 +303,7 @@ namespace RFCavityData refpart.z = z + slice_ds*pz/bgi; // compute final value of beta*gamma - amrex::ParticleReal const bgf = sqrt(pow(ptf, 2) - 1.0_prt); + amrex::ParticleReal const bgf = std::sqrt(std::pow(ptf, 2) - 1.0_prt); // advance momentum (px,py,pz) refpart.px = px*bgf/bgi; @@ -367,14 +372,14 @@ namespace RFCavityData efieldint = z*efield; for (int j=1; j < m_ncoef; ++j) { - efield = efield + cos_data[j]*cos(j*2*pi*z/zlen) + - sin_data[j]*sin(j*2*pi*z/zlen); - efieldp = efieldp-j*2*pi*cos_data[j]*sin(j*2*pi*z/zlen)/zlen + - j*2*pi*sin_data[j]*cos(j*2*pi*z/zlen)/zlen; - efieldpp = efieldpp- pow(j*2*pi*cos_data[j]/zlen,2) *cos(j*2*pi*z/zlen) - - pow(j*2*pi*sin_data[j]/zlen,2) *sin(j*2*pi*z/zlen); - efieldint = efieldint + zlen*cos_data[j]*sin(j*2*pi*z/zlen)/(j*2*pi) - - zlen*sin_data[j]*cos(j*2*pi*z/zlen)/(j*2*pi); + efield = efield + cos_data[j] * std::cos(j*2*pi*z/zlen) + + sin_data[j] * std::sin(j*2*pi*z/zlen); + efieldp = efieldp-j*2*pi*cos_data[j] * std::sin(j*2*pi*z/zlen)/zlen + + j*2*pi*sin_data[j] * std::cos(j*2*pi*z/zlen)/zlen; + efieldpp = efieldpp- std::pow(j*2*pi*cos_data[j]/zlen,2) * std::cos(j*2*pi*z/zlen) - + std::pow(j*2*pi*sin_data[j]/zlen,2) * std::sin(j*2*pi*z/zlen); + efieldint = efieldint + zlen*cos_data[j] * std::sin(j*2*pi*z/zlen)/(j*2*pi) - + zlen*sin_data[j] * std::cos(j*2*pi*z/zlen)/(j*2*pi); } } else // endpoint of the RF, outsize zlen @@ -382,7 +387,7 @@ namespace RFCavityData efieldint = std::copysign(z, z)*zmid*0.5_prt*cos_data[0];; for (int j=1; j < m_ncoef; ++j) { - efieldint = efieldint - zlen*sin_data[j]*cos(j*pi)/(j*2*pi); + efieldint = efieldint - zlen*sin_data[j] * std::cos(j*pi)/(j*2*pi); } } return std::make_tuple(efield, efieldp, efieldint); @@ -408,7 +413,7 @@ namespace RFCavityData amrex::ParticleReal const pt = refpart.pt; if (pt < -1.0_prt) { - refpart.t = t + tau/sqrt(1.0_prt - pow(pt, -2)); + refpart.t = t + tau/std::sqrt(1.0_prt - std::pow(pt, -2)); refpart.pt = pt; } else { @@ -459,17 +464,17 @@ namespace RFCavityData // push the linear map equations amrex::Array2D const R = refpart.map; amrex::ParticleReal const s = tau/refpart.beta_gamma(); - amrex::ParticleReal const L = E0*ezp*sin(k*t+phi)/(2.0_prt*k); + amrex::ParticleReal const L = E0*ezp * std::sin(k*t+phi)/(2.0_prt*k); refpart.map(1,1) = (1.0_prt-s*L)*R(1,1) + s*R(2,1); refpart.map(1,2) = (1.0_prt-s*L)*R(1,2) + s*R(2,2); - refpart.map(2,1) = -s*pow(L,2)*R(1,1) + (1.0_prt+s*L)*R(2,1); - refpart.map(2,2) = -s*pow(L,2)*R(1,2) + (1.0_prt+s*L)*R(2,2); + refpart.map(2,1) = -s * std::pow(L,2)*R(1,1) + (1.0_prt+s*L)*R(2,1); + refpart.map(2,2) = -s * std::pow(L,2)*R(1,2) + (1.0_prt+s*L)*R(2,2); refpart.map(3,3) = (1.0_prt-s*L)*R(3,3) + s*R(4,3); refpart.map(3,4) = (1.0_prt-s*L)*R(3,4) + s*R(4,4); - refpart.map(4,3) = -s*pow(L,2)*R(3,3) + (1.0_prt+s*L)*R(4,3); - refpart.map(4,4) = -s*pow(L,2)*R(3,4) + (1.0_prt+s*L)*R(4,4); + refpart.map(4,3) = -s * std::pow(L,2)*R(3,3) + (1.0_prt+s*L)*R(4,3); + refpart.map(4,4) = -s * std::pow(L,2)*R(3,4) + (1.0_prt+s*L)*R(4,4); } /** This pushes the reference particle and the linear map matrix @@ -506,12 +511,12 @@ namespace RFCavityData amrex::ignore_unused(ezf); refpart.t = t; - refpart.pt = pt - E0*(ezintf-ezint)*cos(k*t+phi); + refpart.pt = pt - E0*(ezintf-ezint) * std::cos(k*t+phi); // push the linear map equations amrex::Array2D const R = refpart.map; - amrex::ParticleReal const M = E0*(ezintf-ezint)*k*sin(k*t+phi); - amrex::ParticleReal const L = E0*(ezpf-ezp)*sin(k*t+phi)/(2.0_prt*k)+M/2.0_prt; + amrex::ParticleReal const M = E0*(ezintf-ezint)*k * std::sin(k*t+phi); + amrex::ParticleReal const L = E0*(ezpf-ezp) * std::sin(k*t+phi)/(2.0_prt*k)+M/2.0_prt; refpart.map(2,1) = L*R(1,1) + R(2,1); refpart.map(2,2) = L*R(1,2) + R(2,2); diff --git a/src/particles/elements/Sbend.H b/src/particles/elements/Sbend.H index 605be632b..5fa7c0080 100644 --- a/src/particles/elements/Sbend.H +++ b/src/particles/elements/Sbend.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -26,7 +27,8 @@ namespace impactx { struct Sbend - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -42,6 +44,7 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ Sbend ( amrex::ParticleReal ds, @@ -49,9 +52,11 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_rc(rc) { @@ -103,8 +108,8 @@ namespace impactx // access reference particle values to find beta*gamma^2 amrex::ParticleReal const pt_ref = refpart.pt; - amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; - amrex::ParticleReal const bet = sqrt(betgam2/(1.0_prt + betgam2)); + amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt; + amrex::ParticleReal const bet = std::sqrt(betgam2/(1.0_prt + betgam2)); // calculate expensive terms once amrex::ParticleReal const theta = slice_ds/m_rc; @@ -162,7 +167,7 @@ namespace impactx // assign intermediate parameter amrex::ParticleReal const theta = slice_ds/m_rc; - amrex::ParticleReal const B = sqrt(pow(pt,2)-1.0_prt)/m_rc; + amrex::ParticleReal const B = std::sqrt(std::pow(pt,2)-1.0_prt)/m_rc; // calculate expensive terms once auto const [sin_theta, cos_theta] = amrex::Math::sincos(theta); diff --git a/src/particles/elements/ShortRF.H b/src/particles/elements/ShortRF.H index b7fa316f4..fb8a4dcbd 100644 --- a/src/particles/elements/ShortRF.H +++ b/src/particles/elements/ShortRF.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct ShortRF - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::Alignment, public elements::NoFinalize @@ -44,6 +46,7 @@ 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 name a user defined and not necessarily unique name of the element */ ShortRF ( amrex::ParticleReal V, @@ -51,9 +54,11 @@ namespace impactx amrex::ParticleReal phase, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, - amrex::ParticleReal rotation_degree = 0 + amrex::ParticleReal rotation_degree = 0, + std::optional name = std::nullopt ) - : Alignment(dx, dy, rotation_degree), + : Named(name), + Alignment(dx, dy, rotation_degree), m_V(V), m_freq(freq), m_phase(phase) { } @@ -99,9 +104,9 @@ namespace impactx // access reference particle values (final, initial): amrex::ParticleReal const ptf_ref = refpart.pt; - amrex::ParticleReal const pti_ref = ptf_ref + m_V*cos(phi); - amrex::ParticleReal const bgf = sqrt(pow(ptf_ref, 2) - 1.0_prt); - amrex::ParticleReal const bgi = sqrt(pow(pti_ref, 2) - 1.0_prt); + amrex::ParticleReal const pti_ref = ptf_ref + m_V * std::cos(phi); + amrex::ParticleReal const bgf = std::sqrt(std::pow(ptf_ref, 2) - 1.0_prt); + amrex::ParticleReal const bgi = std::sqrt(std::pow(pti_ref, 2) - 1.0_prt); // initial conversion from static to dynamic units: px = px*bgi; @@ -124,7 +129,7 @@ namespace impactx pyout = py; // tout = t; - ptout = pt - m_V*cos(k*t + phi) + m_V*cos(phi); + ptout = pt - m_V * std::cos(k*t + phi) + m_V * std::cos(phi); // assign updated values x = xout; @@ -170,14 +175,14 @@ namespace impactx amrex::ParticleReal const phi = m_phase*(pi/180.0_prt); // compute intial value of beta*gamma - amrex::ParticleReal const bgi = sqrt(pow(pt, 2) - 1.0_prt); + amrex::ParticleReal const bgi = std::sqrt(std::pow(pt, 2) - 1.0_prt); // advance pt - refpart.pt = pt - m_V*cos(phi); + refpart.pt = pt - m_V * std::cos(phi); // compute final value of beta*gamma amrex::ParticleReal const ptf = refpart.pt; - amrex::ParticleReal const bgf = sqrt(pow(ptf, 2) - 1.0_prt); + amrex::ParticleReal const bgf = std::sqrt(std::pow(ptf, 2) - 1.0_prt); // advance position (x,y,z,t) refpart.x = x; diff --git a/src/particles/elements/SoftQuad.H b/src/particles/elements/SoftQuad.H index 89a6c4755..2637d638e 100644 --- a/src/particles/elements/SoftQuad.H +++ b/src/particles/elements/SoftQuad.H @@ -14,6 +14,7 @@ #include "particles/integrators/Integrators.H" #include "mixin/alignment.H" #include "mixin/beamoptic.H" +#include "mixin/named.H" #include "mixin/thick.H" #include @@ -111,7 +112,8 @@ namespace SoftQuadrupoleData } // namespace SoftQuadrupoleData struct SoftQuadrupole - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment { @@ -130,6 +132,7 @@ namespace SoftQuadrupoleData * @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 a user defined and not necessarily unique name of the element */ SoftQuadrupole ( amrex::ParticleReal ds, @@ -140,9 +143,11 @@ namespace SoftQuadrupoleData amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, int mapsteps = 1, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_gscale(gscale), m_mapsteps(mapsteps), m_id(SoftQuadrupoleData::next_id) { @@ -285,7 +290,7 @@ namespace SoftQuadrupoleData amrex::ParticleReal const slice_ds = m_ds / nslice(); // compute intial value of beta*gamma - amrex::ParticleReal const bgi = sqrt(pow(pt, 2) - 1.0_prt); + amrex::ParticleReal const bgi = std::sqrt(std::pow(pt, 2) - 1.0_prt); // call integrator to advance (t,pt) amrex::ParticleReal const zin = s - sedge; @@ -312,7 +317,7 @@ namespace SoftQuadrupoleData refpart.z = z + slice_ds*pz/bgi; // compute final value of beta*gamma - amrex::ParticleReal const bgf = sqrt(pow(ptf, 2) - 1.0_prt); + amrex::ParticleReal const bgf = std::sqrt(std::pow(ptf, 2) - 1.0_prt); // advance momentum (px,py,pz) refpart.px = px*bgf/bgi; @@ -362,12 +367,12 @@ namespace SoftQuadrupoleData bfieldint = z*bfield; for (int j=1; j < m_ncoef; ++j) { - bfield = bfield + cos_data[j] * cos(j * 2 * pi * z / zlen) + - sin_data[j] * sin(j * 2 * pi * z / zlen); - bfieldp = bfieldp - j * 2 * pi * cos_data[j] * sin(j * 2 * pi * z / zlen) / zlen + - j * 2 * pi * sin_data[j] * cos(j * 2 * pi * z / zlen) / zlen; - bfieldint = bfieldint + zlen * cos_data[j] * sin(j * 2 * pi * z / zlen) / (j * 2 * pi) - - zlen * sin_data[j] * cos(j * 2 * pi * z / zlen) / (j * 2 * pi); + bfield = bfield + cos_data[j] *std::cos(j * 2 * pi * z / zlen) + + sin_data[j] *std::sin(j * 2 * pi * z / zlen); + bfieldp = bfieldp - j * 2 * pi * cos_data[j] *std::sin(j * 2 * pi * z / zlen) / zlen + + j * 2 * pi * sin_data[j] *std::cos(j * 2 * pi * z / zlen) / zlen; + bfieldint = bfieldint + zlen * cos_data[j] *std::sin(j * 2 * pi * z / zlen) / (j * 2 * pi) - + zlen * sin_data[j] *std::cos(j * 2 * pi * z / zlen) / (j * 2 * pi); } } return std::make_tuple(bfield, bfieldp, bfieldint); @@ -394,7 +399,7 @@ namespace SoftQuadrupoleData amrex::ParticleReal const z = zeval; if (pt < -1.0_prt) { - refpart.t = t + tau/sqrt(1.0_prt - pow(pt, -2)); + refpart.t = t + tau/std::sqrt(1.0_prt - std::pow(pt, -2)); refpart.pt = pt; } else { diff --git a/src/particles/elements/SoftSol.H b/src/particles/elements/SoftSol.H index e3f79efc2..f5263fe20 100644 --- a/src/particles/elements/SoftSol.H +++ b/src/particles/elements/SoftSol.H @@ -14,6 +14,7 @@ #include "particles/integrators/Integrators.H" #include "mixin/alignment.H" #include "mixin/beamoptic.H" +#include "mixin/named.H" #include "mixin/thick.H" #include @@ -116,7 +117,8 @@ namespace SoftSolenoidData } // namespace SoftSolenoidData struct SoftSolenoid - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment { @@ -140,6 +142,7 @@ namespace SoftSolenoidData * @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 a user defined and not necessarily unique name of the element */ SoftSolenoid ( amrex::ParticleReal ds, @@ -151,9 +154,11 @@ namespace SoftSolenoidData amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, int mapsteps = 1, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_bscale(bscale), m_unit(unit), m_mapsteps(mapsteps), m_id(SoftSolenoidData::next_id) { @@ -296,7 +301,7 @@ namespace SoftSolenoidData amrex::ParticleReal const slice_ds = m_ds / nslice(); // compute intial value of beta*gamma - amrex::ParticleReal const bgi = sqrt(pow(pt, 2) - 1.0_prt); + amrex::ParticleReal const bgi = std::sqrt(std::pow(pt, 2) - 1.0_prt); // call integrator to advance (t,pt) amrex::ParticleReal const zin = s - sedge; @@ -321,7 +326,7 @@ namespace SoftSolenoidData refpart.z = z + slice_ds*pz/bgi; // compute final value of beta*gamma - amrex::ParticleReal const bgf = sqrt(pow(ptf, 2) - 1.0_prt); + amrex::ParticleReal const bgf = std::sqrt(std::pow(ptf, 2) - 1.0_prt); // advance momentum (px,py,pz) refpart.px = px*bgf/bgi; @@ -371,12 +376,12 @@ namespace SoftSolenoidData bfieldint = z*bfield; for (int j=1; j < m_ncoef; ++j) { - bfield = bfield + cos_data[j]*cos(j*2*pi*z/zlen) + - sin_data[j]*sin(j*2*pi*z/zlen); - bfieldp = bfieldp-j*2*pi*cos_data[j]*sin(j*2*pi*z/zlen)/zlen + - j*2*pi*sin_data[j]*cos(j*2*pi*z/zlen)/zlen; - bfieldint = bfieldint + zlen*cos_data[j]*sin(j*2*pi*z/zlen)/(j*2*pi) - - zlen*sin_data[j]*cos(j*2*pi*z/zlen)/(j*2*pi); + bfield = bfield + cos_data[j] * std::cos(j*2*pi*z/zlen) + + sin_data[j] * std::sin(j*2*pi*z/zlen); + bfieldp = bfieldp-j*2*pi*cos_data[j] * std::sin(j*2*pi*z/zlen)/zlen + + j*2*pi*sin_data[j] * std::cos(j*2*pi*z/zlen)/zlen; + bfieldint = bfieldint + zlen*cos_data[j] * std::sin(j*2*pi*z/zlen)/(j*2*pi) - + zlen*sin_data[j] * std::cos(j*2*pi*z/zlen)/(j*2*pi); } } return std::make_tuple(bfield, bfieldp, bfieldint); @@ -403,7 +408,7 @@ namespace SoftSolenoidData amrex::ParticleReal const z = zeval; if (pt < -1.0_prt) { - refpart.t = t + tau/sqrt(1.0_prt - pow(pt, -2)); + refpart.t = t + tau/std::sqrt(1.0_prt - std::pow(pt, -2)); refpart.pt = pt; } else { @@ -466,7 +471,7 @@ namespace SoftSolenoidData // push the linear map equations amrex::Array2D const R = refpart.map; amrex::ParticleReal const alpha = B0*bz/2.0_prt; - amrex::ParticleReal const alpha2 = pow(alpha,2); + amrex::ParticleReal const alpha2 = std::pow(alpha,2); refpart.map(2,1) = R(2,1) - tau*alpha2*R(1,1); refpart.map(2,2) = R(2,2) - tau*alpha2*R(1,2); @@ -515,8 +520,8 @@ namespace SoftSolenoidData // push the linear map equations amrex::Array2D const R = refpart.map; amrex::ParticleReal const theta = tau*B0*bz/2.0_prt; - amrex::ParticleReal const cs = cos(theta); - amrex::ParticleReal const sn = sin(theta); + amrex::ParticleReal const cs = std::cos(theta); + amrex::ParticleReal const sn = std::sin(theta); refpart.map(1,1) = R(1,1)*cs + R(3,1)*sn; refpart.map(1,2) = R(1,2)*cs + R(3,2)*sn; diff --git a/src/particles/elements/Sol.H b/src/particles/elements/Sol.H index 3753aafff..608f0d9ad 100644 --- a/src/particles/elements/Sol.H +++ b/src/particles/elements/Sol.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thick.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -26,7 +27,8 @@ namespace impactx { struct Sol - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thick, public elements::Alignment, public elements::NoFinalize @@ -43,6 +45,7 @@ namespace impactx * @param dy vertical translation error in m * @param rotation_degree rotation error in the transverse plane [degrees] * @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 */ Sol ( amrex::ParticleReal ds, @@ -50,9 +53,11 @@ namespace impactx amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, amrex::ParticleReal rotation_degree = 0, - int nslice = 1 + int nslice = 1, + std::optional name = std::nullopt ) - : Thick(ds, nslice), + : Named(name), + Thick(ds, nslice), Alignment(dx, dy, rotation_degree), m_ks(ks) { @@ -94,7 +99,7 @@ namespace impactx // access reference particle values to find beta*gamma^2 amrex::ParticleReal const pt_ref = refpart.pt; - amrex::ParticleReal const betgam2 = pow(pt_ref, 2) - 1.0_prt; + amrex::ParticleReal const betgam2 = std::pow(pt_ref, 2) - 1.0_prt; // compute phase advance per unit length (in rad/m) and // rotation angle (in rad) @@ -168,7 +173,7 @@ namespace impactx amrex::ParticleReal const slice_ds = m_ds / nslice(); // assign intermediate parameter - amrex::ParticleReal const step = slice_ds / sqrt(pow(pt,2)-1.0_prt); + amrex::ParticleReal const step = slice_ds / std::sqrt(std::pow(pt,2) - 1.0_prt); // advance position and momentum (straight element) refpart.x = x + step*px; diff --git a/src/particles/elements/TaperedPL.H b/src/particles/elements/TaperedPL.H index fb618d823..9a107679e 100644 --- a/src/particles/elements/TaperedPL.H +++ b/src/particles/elements/TaperedPL.H @@ -14,6 +14,7 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include @@ -25,7 +26,8 @@ namespace impactx { struct TaperedPL - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::Alignment, public elements::NoFinalize @@ -46,6 +48,7 @@ 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 name a user defined and not necessarily unique name of the element */ TaperedPL ( amrex::ParticleReal k, @@ -53,9 +56,11 @@ namespace impactx int unit, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, - amrex::ParticleReal rotation_degree = 0 + amrex::ParticleReal rotation_degree = 0, + std::optional name = std::nullopt ) - : Alignment(dx, dy, rotation_degree), + : Named(name), + Alignment(dx, dy, rotation_degree), m_k(k), m_taper(taper), m_unit(unit) { } diff --git a/src/particles/elements/ThinDipole.H b/src/particles/elements/ThinDipole.H index ecfd78e0d..84bcc57e5 100644 --- a/src/particles/elements/ThinDipole.H +++ b/src/particles/elements/ThinDipole.H @@ -14,15 +14,18 @@ #include "mixin/alignment.H" #include "mixin/beamoptic.H" #include "mixin/thin.H" +#include "mixin/named.H" #include "mixin/nofinalize.H" #include #include + namespace impactx { struct ThinDipole - : public elements::BeamOptic, + : public elements::Named, + public elements::BeamOptic, public elements::Thin, public elements::Alignment, public elements::NoFinalize @@ -44,15 +47,18 @@ 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 name a user defined and not necessarily unique name of the element */ ThinDipole ( amrex::ParticleReal theta, amrex::ParticleReal rc, amrex::ParticleReal dx = 0, amrex::ParticleReal dy = 0, - amrex::ParticleReal rotation_degree = 0 + amrex::ParticleReal rotation_degree = 0, + std::optional name = std::nullopt ) - : Alignment(dx, dy, rotation_degree), + : Named(name), + Alignment(dx, dy, rotation_degree), m_theta(theta * degree2rad), m_rc(rc) { @@ -104,7 +110,7 @@ namespace impactx amrex::ParticleReal ptout = pt; // compute the function expressing dp/p in terms of pt (labeled f in Ripken etc.) - amrex::ParticleReal f = -1.0_prt + sqrt(1.0_prt - 2.0_prt*pt/beta_ref + pow(pt,2)); + amrex::ParticleReal f = -1.0_prt + std::sqrt(1.0_prt - 2.0_prt*pt/beta_ref + std::pow(pt,2)); amrex::ParticleReal fprime = (1.0_prt - beta_ref*pt)/(beta_ref*(1.0_prt + f)); // compute the effective (equivalent) arc length and curvature @@ -113,7 +119,7 @@ namespace impactx // advance position and momentum x = xout; - pxout = px - pow(kx,2) * ds * xout + kx * ds * f; //eq (3.2b) + pxout = px - std::pow(kx,2) * ds * xout + kx * ds * f; //eq (3.2b) y = yout; pyout = py; diff --git a/src/particles/elements/mixin/named.H b/src/particles/elements/mixin/named.H new file mode 100644 index 000000000..f06a6d86c --- /dev/null +++ b/src/particles/elements/mixin/named.H @@ -0,0 +1,153 @@ +/* Copyright 2022-2024 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_NAMED_H +#define IMPACTX_ELEMENTS_MIXIN_NAMED_H + +#include "particles/ImpactXParticleContainer.H" + +#include +#include + +#include +#include +#include +#include + + +namespace impactx::elements +{ + /** This is a helper class for lattice elements with a user-defined name + */ + struct Named + { + /** Overwrite the name of the element + * + * @param new_name set a new name on the element + */ + AMREX_GPU_HOST + void set_name ( + std::string const & new_name + ) + { + // free old name + if (m_name != nullptr) { + delete[] m_name; + m_name = nullptr; + } + + // set new name + if (new_name.size() > 0) { + m_name = new char[new_name.size() + 1]; + std::strcpy(m_name, new_name.c_str()); + } + } + + /** A user-named element + * + * @param name a user defined and not necessarily unique name of the element + */ + AMREX_GPU_HOST + Named ( + std::optional name + ) + { + if (name.has_value()) { + set_name(*name); + } + } + + AMREX_GPU_HOST_DEVICE + ~Named () + { + AMREX_IF_ON_HOST(( + if (m_name != nullptr) { + delete[] m_name; + m_name = nullptr; + } + )) + } + + AMREX_GPU_HOST + Named (Named const & other) + { + if (other.has_name()) { + m_name = new char[std::strlen(other.m_name) + 1]; + std::strcpy(m_name, other.m_name); + } + } + + AMREX_GPU_HOST + Named& operator=(Named const & other) + { + if (&other != this) { + if (other.has_name()) { + m_name = new char[std::strlen(other.m_name) + 1]; + std::strcpy(m_name, other.m_name); + } + } + return *this; + } + + AMREX_GPU_HOST_DEVICE + Named ([[maybe_unused]] Named && other) noexcept + { + AMREX_IF_ON_HOST(( + std::swap(this->m_name, other.m_name); + other.m_name = nullptr; + )) + } + + AMREX_GPU_HOST_DEVICE + Named& operator=([[maybe_unused]] Named && other) noexcept + { + AMREX_IF_ON_HOST(( + std::swap(this->m_name, other.m_name); + other.m_name = nullptr; + )) + return *this; + } + + /** Return the user provided name of the element + * + * @return user defined and not necessarily unique name + */ + AMREX_FORCE_INLINE + std::string name () const + { + if (!has_name()) { + throw std::runtime_error("Name not set on element!"); + } + return std::string(m_name); + } + + /** Return true if the user provided a name for this element + * + * @return true if the user provided a name + */ + AMREX_FORCE_INLINE + bool has_name () const + { + return m_name != nullptr; + } + + private: + // Implementation note: + // This is used as a mixin class in elements that are copied to GPU. GPU compilers copy + // a whole element by its sizeof(T). + // To save on this copy operation at kernel start, this is implemented + // as a simple C pointer (8 bytes), contrary to a std::string (32 bytes) or + // a std::optional (40 bytes). m_name points to host-side memory and + // must not be dereferenced (used) on GPU. + char * m_name = nullptr; //! a user defined and not necessarily unique name of the element + }; + +} // namespace impactx::elements + +#endif // IMPACTX_ELEMENTS_MIXIN_NAMED_H diff --git a/src/particles/integrators/Integrators.H b/src/particles/integrators/Integrators.H index 636f04384..1bd770baf 100644 --- a/src/particles/integrators/Integrators.H +++ b/src/particles/integrators/Integrators.H @@ -137,7 +137,7 @@ namespace impactx::integrators // initialize numerical integration parameters amrex::ParticleReal const dz = (zout-zin)/nsteps; - amrex::ParticleReal const alpha = 1.0_prt - pow(2.0_prt,1.0/3.0); + amrex::ParticleReal const alpha = 1.0_prt - std::pow(2.0_prt,1.0/3.0); amrex::ParticleReal const tau2 = dz/(1.0_prt + alpha); amrex::ParticleReal const tau1 = tau2/2.0_prt; amrex::ParticleReal const tau3 = alpha*tau1; diff --git a/src/particles/transformation/CoordinateTransformation.cpp b/src/particles/transformation/CoordinateTransformation.cpp index cbf105533..299c95972 100644 --- a/src/particles/transformation/CoordinateTransformation.cpp +++ b/src/particles/transformation/CoordinateTransformation.cpp @@ -62,7 +62,7 @@ namespace impactx::transformation amrex::ParticleReal *const AMREX_RESTRICT part_pz = soa_real[RealSoA::pz].dataPtr(); // Design value of pz/mc = beta*gamma - amrex::ParticleReal const pzd = sqrt(pow(pd, 2) - 1.0); + amrex::ParticleReal const pzd = std::sqrt(std::pow(pd, 2) - 1.0); ToFixedS const to_s(pzd); amrex::ParallelFor(np, [=] AMREX_GPU_DEVICE(long i) { diff --git a/src/particles/transformation/ToFixedS.H b/src/particles/transformation/ToFixedS.H index 10cb1b297..e18d4b136 100644 --- a/src/particles/transformation/ToFixedS.H +++ b/src/particles/transformation/ToFixedS.H @@ -59,9 +59,9 @@ namespace impactx::transformation using namespace amrex::literals; // compute value of reference ptd = -gamma - amrex::ParticleReal const argd = 1.0_prt + pow(m_pzd, 2); + amrex::ParticleReal const argd = 1.0_prt + std::pow(m_pzd, 2); AMREX_ASSERT_WITH_MESSAGE(argd > 0.0_prt, "invalid ptd arg (<=0)"); - amrex::ParticleReal const ptdf = argd > 0.0_prt ? -sqrt(argd) : -1.0_prt; + amrex::ParticleReal const ptdf = argd > 0.0_prt ? -std::sqrt(argd) : -1.0_prt; // transform momenta to dynamic units (e.g., so that momenta are // normalized by mc): @@ -70,9 +70,9 @@ namespace impactx::transformation pz = pz * m_pzd; // compute value of particle pt = -gamma - amrex::ParticleReal const arg = 1.0_prt + pow(m_pzd + pz, 2) + pow(px, 2) + pow(py, 2); + amrex::ParticleReal const arg = 1.0_prt + std::pow(m_pzd + pz, 2) + std::pow(px, 2) + std::pow(py, 2); AMREX_ASSERT_WITH_MESSAGE(arg > 0.0_prt, "invalid pt arg (<=0)"); - amrex::ParticleReal const ptf = arg > 0.0_prt ? -sqrt(arg) : -1.0_prt; + amrex::ParticleReal const ptf = arg > 0.0_prt ? -std::sqrt(arg) : -1.0_prt; // transform position and momentum (from fixed t to fixed s) x = x - px * z / (m_pzd + pz); diff --git a/src/particles/transformation/ToFixedT.H b/src/particles/transformation/ToFixedT.H index 577436ea3..af90cc132 100644 --- a/src/particles/transformation/ToFixedT.H +++ b/src/particles/transformation/ToFixedT.H @@ -62,9 +62,9 @@ namespace impactx::transformation constexpr amrex::ParticleReal tol = 1.0e-8_prt; // compute value of reference pzd = beta*gamma - amrex::ParticleReal const argd = -1.0_prt + pow(m_ptd, 2); + amrex::ParticleReal const argd = -1.0_prt + std::pow(m_ptd, 2); // AMREX_ASSERT_WITH_MESSAGE(argd > 0.0_prt, "invalid pzd arg (<=0)"); - amrex::ParticleReal const pzdf = argd > 0.0_prt ? sqrt(argd) : tol; + amrex::ParticleReal const pzdf = argd > 0.0_prt ? std::sqrt(argd) : tol; // transform momenta to dynamic units (eg, so that momenta are // normalized by mc): @@ -73,9 +73,9 @@ namespace impactx::transformation pt = pt * pzdf; // compute value of particle pz = beta*gamma - amrex::ParticleReal const arg = -1.0_prt + pow(m_ptd+pt, 2) - pow(px, 2) - pow(py, 2); + amrex::ParticleReal const arg = -1.0_prt + std::pow(m_ptd+pt, 2) - std::pow(px, 2) - std::pow(py, 2); // AMREX_ASSERT_WITH_MESSAGE(arg > 0.0_prt, "invalid pz arg (<=0)"); - amrex::ParticleReal const pzf = arg > 0.0_prt ? sqrt(arg) : tol; + amrex::ParticleReal const pzf = arg > 0.0_prt ? std::sqrt(arg) : tol; // transform position and momentum (from fixed s to fixed t) x = x + px*t/(m_ptd+pt); diff --git a/src/python/elements.cpp b/src/python/elements.cpp index 82f6ec6ee..7d4a33f76 100644 --- a/src/python/elements.cpp +++ b/src/python/elements.cpp @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include @@ -62,6 +64,73 @@ namespace "Push first the reference particle, then all other particles." ); } + + /** Helper to format {key, value} pairs + * + * Expected outcome is ", key=value" with key as a string and appropriate formatting for value. + * + * @tparam T value type + * @param arg a key-value pair + * @return a string of the form ", key=value" + */ + template + std::string + format_extra (std::pair const & arg) + { + if constexpr (std::is_floating_point_v) + { + // float + // TODO: format as scientific number + return std::string(", ") + .append(arg.first) + .append("=") + .append(std::to_string(arg.second)); + } + else if constexpr (std::is_integral_v) + { + // int + return std::string(", ") + .append(arg.first) + .append("=") + .append(std::to_string(arg.second)); + } else + { + // already a string + return std::string(", ") + .append(arg.first) + .append("=") + .append(arg.second); + } + } + + /** Helper to build a __repr__ for an Element + * + * @tparam T_Element type for the C++ element type + * @tparam ExtraArgs type for pairs of name, value to add + * @param el the current element + * @param args pars of name, value to add + * @return a string suitable for Python's __repr__ + */ + template + std::string element_name (T_Element const & el, std::pair const &... args) + { + // Fixed element type name, e.g., "SBend" + std::string const type = T_Element::type; + + // User-provided element name, e.g., "name=bend1" + std::string const name = el.has_name() ? ", name=" + el.name() : ""; + + // Noteworthy element parameters, e.g., "ds=2.3, key=value, ..." + std::string extra_args; + ((extra_args.append(format_extra(args))), ...); + + // combine it all together + return ""; + } } void init_elements(py::module& m) @@ -73,6 +142,15 @@ void init_elements(py::module& m) // mixin classes + py::class_(me, "Named") + .def_property("name", + [](elements::Named & nm) { return nm.name(); }, + [](elements::Named & nm, std::string new_name) { nm.set_name(new_name); }, + "segment length in m" + ) + .def_property_readonly("has_name", &elements::Named::has_name) + ; + py::class_(me, "Thick") .def(py::init< amrex::ParticleReal, @@ -194,11 +272,14 @@ 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 */) { - return std::string(""); + [](Aperture const & ap) { + return element_name( + ap, + std::make_pair("shape", ap.shape_name(ap.m_shape)) + ); } ) .def(py::init([]( @@ -207,7 +288,8 @@ void init_elements(py::module& m) std::string const & shape, amrex::ParticleReal dx, amrex::ParticleReal dy, - amrex::ParticleReal rotation_degree + amrex::ParticleReal rotation_degree, + std::optional name ) { if (shape != "rectangular" && shape != "elliptical") @@ -216,7 +298,7 @@ void init_elements(py::module& m) Aperture::Shape const s = shape == "rectangular" ? Aperture::Shape::rectangular : Aperture::Shape::elliptical; - return new Aperture(xmax, ymax, s, dx, dy, rotation_degree); + return new Aperture(xmax, ymax, s, dx, dy, rotation_degree, name); }), py::arg("xmax"), py::arg("ymax"), @@ -224,20 +306,13 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("name") = py::none(), "A short collimator element applying a transverse aperture boundary." ) .def_property("shape", [](Aperture & ap) { - switch (ap.m_shape) - { - case Aperture::Shape::rectangular : // default - return "rectangular"; - case Aperture::Shape::elliptical : - return "elliptical"; - default: - throw std::runtime_error("Unknown shape"); - } + return ap.shape_name(ap.m_shape); }, [](Aperture & ap, std::string const & shape) { @@ -263,14 +338,14 @@ 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) { - std::string r = ""); - return r; + return element_name( + chr_drift, + std::make_pair("ds", chr_drift.ds()) + ); } ) .def(py::init< @@ -278,28 +353,29 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "A Drift with chromatic effects included." ) ; 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) { - std::string r = ""); - return r; + return element_name( + chr_quad, + std::make_pair("ds", chr_quad.ds()), + std::make_pair("k", chr_quad.m_k) + ); } ) .def(py::init< @@ -309,7 +385,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("k"), @@ -318,6 +395,7 @@ void init_elements(py::module& m) py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "A Quadrupole magnet with chromatic effects included." ) .def_property("k", @@ -333,16 +411,15 @@ 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) { - std::string r = ""); - return r; + return element_name( + chr_pl_lens, + std::make_pair("ds", chr_pl_lens.ds()), + std::make_pair("k", chr_pl_lens.m_k) + ); } ) .def(py::init< @@ -352,7 +429,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("k"), @@ -361,6 +439,7 @@ void init_elements(py::module& m) py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "An active Plasma Lens with chromatic effects included." ) .def_property("k", @@ -376,18 +455,16 @@ 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) { - std::string r = ""); - return r; + return element_name( + chr_acc, + std::make_pair("ds", chr_acc.ds()), + std::make_pair("ez", chr_acc.m_ez), + std::make_pair("bz", chr_acc.m_bz) + ); } ) .def(py::init< @@ -397,7 +474,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("ez"), @@ -406,6 +484,7 @@ void init_elements(py::module& m) py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "A region of Uniform Acceleration, with chromatic effects included." ) .def_property("ez", @@ -421,20 +500,17 @@ 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) { - std::string r = ""); - return r; + return element_name( + constf, + std::make_pair("ds", constf.ds()), + std::make_pair("kx", constf.m_kx), + std::make_pair("ky", constf.m_ky), + std::make_pair("kt", constf.m_kt) + ); } ) .def(py::init< @@ -445,7 +521,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("kx"), @@ -455,6 +532,7 @@ void init_elements(py::module& m) py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "A linear Constant Focusing element." ) .def_property("kx", @@ -475,20 +553,17 @@ 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) { - std::string r = ""); - return r; + return element_name( + dip_edge, + std::make_pair("psi", dip_edge.m_psi), + std::make_pair("rc", dip_edge.m_rc), + std::make_pair("g", dip_edge.m_g), + std::make_pair("K2", dip_edge.m_K2) + ); } ) .def(py::init< @@ -498,7 +573,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - amrex::ParticleReal + amrex::ParticleReal, + std::optional >(), py::arg("psi"), py::arg("rc"), @@ -507,6 +583,7 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("name") = py::none(), "Edge focusing associated with bend entry or exit." ) .def_property("psi", @@ -532,14 +609,14 @@ 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) { - std::string r = ""); - return r; + return element_name( + drift, + std::make_pair("ds", drift.ds()) + ); } ) .def(py::init< @@ -547,26 +624,28 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "A drift." ) ; 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) { - std::string r = ""); - return r; + return element_name( + exact_drift, + std::make_pair("ds", exact_drift.ds()) + ); } ) .def(py::init< @@ -574,30 +653,30 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "A Drift using the exact nonlinear map." ) ; 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) { - std::string r = ""); - return r; + return element_name( + exact_sbend, + std::make_pair("ds", exact_sbend.ds()), + std::make_pair("phi", exact_sbend.m_phi), + std::make_pair("B", exact_sbend.m_B) + ); } ) .def(py::init< @@ -607,7 +686,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("phi"), @@ -616,6 +696,7 @@ void init_elements(py::module& m) py::arg("dy") = 0, py::arg("rotation") = 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." ) .def_property("phi", @@ -631,16 +712,15 @@ 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) { - std::string r = ""); - return r; + return element_name( + kicker, + std::make_pair("xkick", kicker.m_xkick), + std::make_pair("ykick", kicker.m_ykick) + ); } ) .def(py::init([]( @@ -649,7 +729,8 @@ void init_elements(py::module& m) std::string const & unit, amrex::ParticleReal dx, amrex::ParticleReal dy, - amrex::ParticleReal rotation_degree + amrex::ParticleReal rotation_degree, + std::optional name ) { if (unit != "dimensionless" && unit != "T-m") @@ -658,14 +739,15 @@ void init_elements(py::module& m) Kicker::UnitSystem const u = unit == "dimensionless" ? Kicker::UnitSystem::dimensionless : Kicker::UnitSystem::Tm; - return new Kicker(xkick, ykick, u, dx, dy, rotation_degree); + return new Kicker(xkick, ykick, u, dx, dy, rotation_degree, name); }), - py::arg("xkick"), + py::arg("xkick"), py::arg("ykick"), py::arg("unit") = "dimensionless", py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("name") = py::none(), R"(A thin transverse kicker element. Kicks are for unit "dimensionless" or in "T-m".)" ) .def_property("xkick", @@ -682,18 +764,17 @@ 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) { - std::string r = ""); - return r; + return element_name( + multipole, + std::make_pair("multipole", multipole.m_multipole), + std::make_pair("mfactorial", multipole.m_mfactorial), + std::make_pair("K_normal", multipole.m_Kn), + std::make_pair("K_skew", multipole.m_Ks) + ); } ) .def(py::init< @@ -702,7 +783,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - amrex::ParticleReal + amrex::ParticleReal, + std::optional >(), py::arg("multipole"), py::arg("K_normal"), @@ -710,6 +792,7 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("name") = py::none(), "A general thin multipole element." ) .def_property("multipole", @@ -730,10 +813,10 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_Multipole); - py::class_ py_None(me, "Empty"); - py_None + py::class_ py_Empty(me, "Empty"); + py_Empty .def("__repr__", - [](Empty const & /* none */) { + [](Empty const & /* empty */) { return std::string(""); } ) @@ -741,18 +824,30 @@ void init_elements(py::module& m) "This element does nothing." ) ; - register_beamoptics_push(py_None); + register_beamoptics_push(py_Empty); - py::class_ py_NonlinearLens(me, "NonlinearLens"); + py::class_ py_Marker(me, "Marker"); + py_Marker + .def("__repr__", + [](Marker const & marker) { + return element_name(marker); + } + ) + .def(py::init(), + "This named element does nothing." + ) + ; + register_beamoptics_push(py_Marker); + + py::class_ py_NonlinearLens(me, "NonlinearLens"); py_NonlinearLens .def("__repr__", [](NonlinearLens const & nl) { - std::string r = ""); - return r; + return element_name( + nl, + std::make_pair("knll", nl.m_knll), + std::make_pair("cnll", nl.m_cnll) + ); } ) .def(py::init< @@ -760,13 +855,15 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - amrex::ParticleReal + amrex::ParticleReal, + std::optional >(), py::arg("knll"), py::arg("cnll"), py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("name") = py::none(), "Single short segment of the nonlinear magnetic insert element." ) .def_property("knll", @@ -782,20 +879,23 @@ void init_elements(py::module& m) ; register_beamoptics_push(py_NonlinearLens); - py::class_(me, "Programmable", py::dynamic_attr()) + py::class_(me, "Programmable", py::dynamic_attr()) .def("__repr__", [](Programmable const & prg) { - std::string r = ""); - return r; + return element_name( + prg, + std::make_pair("ds", prg.ds()) + ); } ) .def(py::init< amrex::ParticleReal, - int + int, + std::optional >(), - py::arg("ds") = 0.0, py::arg("nslice") = 1, + py::arg("ds") = 0.0, + py::arg("nslice") = 1, + py::arg("name") = py::none(), "A programmable beam optics element." ) .def_property("nslice", @@ -834,16 +934,15 @@ 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) { - std::string r = ""); - return r; + return element_name( + quad, + std::make_pair("ds", quad.ds()), + std::make_pair("k", quad.m_k) + ); } ) .def(py::init< @@ -852,7 +951,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("k"), @@ -860,6 +960,7 @@ void init_elements(py::module& m) py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "A Quadrupole magnet." ) .def_property("k", @@ -870,20 +971,17 @@ 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) { - std::string r = ""); - return r; + return element_name( + rfc, + std::make_pair("ds", rfc.ds()), + std::make_pair("escale", rfc.m_escale), + std::make_pair("freq", rfc.m_freq), + std::make_pair("phase", rfc.m_phase) + ); } ) .def(py::init< @@ -897,7 +995,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, int, - int + int, + std::optional >(), py::arg("ds"), py::arg("escale"), @@ -910,6 +1009,7 @@ void init_elements(py::module& m) py::arg("rotation") = 0, py::arg("mapsteps") = 1, py::arg("nslice") = 1, + py::arg("name") = py::none(), "An RF cavity." ) .def_property("escale", @@ -937,16 +1037,15 @@ 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) { - std::string r = ""); - return r; + return element_name( + sbend, + std::make_pair("ds", sbend.ds()), + std::make_pair("rc", sbend.m_rc) + ); } ) .def(py::init< @@ -955,7 +1054,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("rc"), @@ -963,6 +1063,7 @@ void init_elements(py::module& m) py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "An ideal sector bend." ) .def_property("rc", @@ -973,18 +1074,16 @@ 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) { - std::string r = ""); - return r; + return element_name( + cfbend, + std::make_pair("ds", cfbend.ds()), + std::make_pair("rc", cfbend.m_rc), + std::make_pair("k", cfbend.m_k) + ); } ) .def(py::init< @@ -994,7 +1093,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("rc"), @@ -1003,6 +1103,7 @@ void init_elements(py::module& m) py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "An ideal combined function bend (sector bend with quadrupole component)." ) .def_property("rc", @@ -1018,16 +1119,15 @@ 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) { - std::string r = ""); - return r; + return element_name( + buncher, + std::make_pair("V", buncher.m_V), + std::make_pair("k", buncher.m_k) + ); } ) .def(py::init< @@ -1035,13 +1135,15 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - amrex::ParticleReal + amrex::ParticleReal, + std::optional >(), py::arg("V"), py::arg("k"), py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("name") = py::none(), "A short linear RF cavity element at zero-crossing for bunching." ) .def_property("V", @@ -1057,18 +1159,16 @@ 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) { - std::string r = ""); - return r; + return element_name( + short_rf, + std::make_pair("V", short_rf.m_V), + std::make_pair("freq", short_rf.m_freq), + std::make_pair("phase", short_rf.m_phase) + ); } ) .def(py::init< @@ -1077,7 +1177,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - amrex::ParticleReal + amrex::ParticleReal, + std::optional >(), py::arg("V"), py::arg("freq"), @@ -1085,6 +1186,7 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("name") = py::none(), "A short RF cavity element." ) .def_property("V", @@ -1105,16 +1207,15 @@ 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) { - std::string r = ""); - return r; + return element_name( + soft_sol, + std::make_pair("ds", soft_sol.ds()), + std::make_pair("bscale", soft_sol.m_bscale) + ); } ) .def(py::init< @@ -1127,7 +1228,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, int, - int + int, + std::optional >(), py::arg("ds"), py::arg("bscale"), @@ -1139,6 +1241,7 @@ void init_elements(py::module& m) py::arg("rotation") = 0, py::arg("mapsteps") = 1, py::arg("nslice") = 1, + py::arg("name") = py::none(), "A soft-edge solenoid." ) .def_property("bscale", @@ -1161,16 +1264,15 @@ 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 & soft_sol) { - std::string r = ""); - return r; + [](Sol const & sol) { + return element_name( + sol, + std::make_pair("ds", sol.ds()), + std::make_pair("ks", sol.m_ks) + ); } ) .def(py::init< @@ -1179,7 +1281,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - int + int, + std::optional >(), py::arg("ds"), py::arg("ks"), @@ -1187,6 +1290,7 @@ void init_elements(py::module& m) py::arg("dy") = 0, py::arg("rotation") = 0, py::arg("nslice") = 1, + py::arg("name") = py::none(), "An ideal hard-edge Solenoid magnet." ) .def_property("ks", @@ -1197,24 +1301,25 @@ 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) { - std::string r = ""); - return r; + return element_name( + prot, + std::make_pair("phi_in", prot.m_phi_in), + std::make_pair("phi_out", prot.m_phi_out) + ); } ) .def(py::init< amrex::ParticleReal, - amrex::ParticleReal + amrex::ParticleReal, + std::optional >(), py::arg("phi_in"), py::arg("phi_out"), + py::arg("name") = py::none(), "An exact pole-face rotation in the x-z plane. Both angles are in degrees." ) .def_property("phi_in", @@ -1230,16 +1335,15 @@ 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) { - std::string r = ""); - return r; + return element_name( + soft_quad, + std::make_pair("ds", soft_quad.ds()), + std::make_pair("gscale", soft_quad.m_gscale) + ); } ) .def(py::init< @@ -1251,7 +1355,8 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, int, - int + int, + std::optional >(), py::arg("ds"), py::arg("gscale"), @@ -1262,6 +1367,7 @@ void init_elements(py::module& m) py::arg("rotation") = 0, py::arg("mapsteps") = 1, py::arg("nslice") = 1, + py::arg("name") = py::none(), "A soft-edge quadrupole." ) .def_property("gscale", @@ -1279,16 +1385,15 @@ 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) { - std::string r = ""); - return r; + return element_name( + thin_dp, + std::make_pair("theta", thin_dp.m_theta), + std::make_pair("rc", thin_dp.m_rc) + ); } ) .def(py::init< @@ -1296,13 +1401,15 @@ void init_elements(py::module& m) amrex::ParticleReal, amrex::ParticleReal, amrex::ParticleReal, - amrex::ParticleReal + amrex::ParticleReal, + std::optional >(), py::arg("theta"), py::arg("rc"), py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("name") = py::none(), "A thin kick model of a dipole bend." ) .def_property("theta", @@ -1318,17 +1425,15 @@ 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) { - std::string r = ""); - return r; + return element_name( + taperedpl, + std::make_pair("k", taperedpl.m_k), + std::make_pair("taper", taperedpl.m_taper) + ); } ) .def(py::init< @@ -1337,7 +1442,8 @@ void init_elements(py::module& m) int, amrex::ParticleReal, amrex::ParticleReal, - amrex::ParticleReal + amrex::ParticleReal, + std::optional >(), py::arg("k"), py::arg("taper"), @@ -1345,6 +1451,7 @@ void init_elements(py::module& m) py::arg("dx") = 0, py::arg("dy") = 0, py::arg("rotation") = 0, + py::arg("name") = py::none(), R"doc(A thin nonlinear plasma lens with transverse (horizontal) taper .. math:: diff --git a/src/python/impactx/impactx_pybind/__init__.pyi b/src/python/impactx/impactx_pybind/__init__.pyi index b6587969b..2d0df0e6d 100644 --- a/src/python/impactx/impactx_pybind/__init__.pyi +++ b/src/python/impactx/impactx_pybind/__init__.pyi @@ -683,6 +683,7 @@ def push( | elements.ExactDrift | elements.ExactSbend | elements.Kicker + | elements.Marker | elements.Multipole | elements.NonlinearLens | elements.Programmable diff --git a/src/python/impactx/impactx_pybind/elements.pyi b/src/python/impactx/impactx_pybind/elements.pyi index dd3427062..86ae8b3c8 100644 --- a/src/python/impactx/impactx_pybind/elements.pyi +++ b/src/python/impactx/impactx_pybind/elements.pyi @@ -26,7 +26,9 @@ __all__ = [ "ExactSbend", "Kicker", "KnownElementsList", + "Marker", "Multipole", + "Named", "NonlinearLens", "PRot", "Programmable", @@ -70,7 +72,7 @@ class Alignment: @rotation.setter def rotation(self, arg1: float) -> None: ... -class Aperture(Thin, Alignment): +class Aperture(Named, Thin, Alignment): def __init__( self, xmax: float, @@ -79,6 +81,7 @@ class Aperture(Thin, Alignment): dx: float = 0, dy: float = 0, rotation: float = 0, + name: str | None = None, ) -> None: """ A short collimator element applying a transverse aperture boundary. @@ -168,9 +171,15 @@ class BeamMonitor(Thin): @tn.setter def tn(self, arg1: float) -> None: ... -class Buncher(Thin, Alignment): +class Buncher(Named, Thin, Alignment): def __init__( - self, V: float, k: float, dx: float = 0, dy: float = 0, rotation: float = 0 + self, + V: float, + k: float, + dx: float = 0, + dy: float = 0, + rotation: float = 0, + name: str | None = None, ) -> None: """ A short linear RF cavity element at zero-crossing for bunching. @@ -197,7 +206,7 @@ class Buncher(Thin, Alignment): @k.setter def k(self, arg1: float) -> None: ... -class CFbend(Thick, Alignment): +class CFbend(Named, Thick, Alignment): def __init__( self, ds: float, @@ -207,6 +216,7 @@ class CFbend(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ An ideal combined function bend (sector bend with quadrupole component). @@ -233,7 +243,7 @@ class CFbend(Thick, Alignment): @rc.setter def rc(self, arg1: float) -> None: ... -class ChrAcc(Thick, Alignment): +class ChrAcc(Named, Thick, Alignment): def __init__( self, ds: float, @@ -243,6 +253,7 @@ class ChrAcc(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ A region of Uniform Acceleration, with chromatic effects included. @@ -269,7 +280,7 @@ class ChrAcc(Thick, Alignment): @ez.setter def ez(self, arg1: float) -> None: ... -class ChrDrift(Thick, Alignment): +class ChrDrift(Named, Thick, Alignment): def __init__( self, ds: float, @@ -277,6 +288,7 @@ class ChrDrift(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ A Drift with chromatic effects included. @@ -289,7 +301,7 @@ class ChrDrift(Thick, Alignment): Push first the reference particle, then all other particles. """ -class ChrPlasmaLens(Thick, Alignment): +class ChrPlasmaLens(Named, Thick, Alignment): def __init__( self, ds: float, @@ -299,6 +311,7 @@ class ChrPlasmaLens(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ An active Plasma Lens with chromatic effects included. @@ -325,7 +338,7 @@ class ChrPlasmaLens(Thick, Alignment): @unit.setter def unit(self, arg1: int) -> None: ... -class ChrQuad(Thick, Alignment): +class ChrQuad(Named, Thick, Alignment): def __init__( self, ds: float, @@ -335,6 +348,7 @@ class ChrQuad(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ A Quadrupole magnet with chromatic effects included. @@ -361,7 +375,7 @@ class ChrQuad(Thick, Alignment): @unit.setter def unit(self, arg1: int) -> None: ... -class ConstF(Thick, Alignment): +class ConstF(Named, Thick, Alignment): def __init__( self, ds: float, @@ -372,6 +386,7 @@ class ConstF(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ A linear Constant Focusing element. @@ -405,7 +420,7 @@ class ConstF(Thick, Alignment): @ky.setter def ky(self, arg1: float) -> None: ... -class DipEdge(Thin, Alignment): +class DipEdge(Named, Thin, Alignment): def __init__( self, psi: float, @@ -415,6 +430,7 @@ class DipEdge(Thin, Alignment): dx: float = 0, dy: float = 0, rotation: float = 0, + name: str | None = None, ) -> None: """ Edge focusing associated with bend entry or exit. @@ -455,7 +471,7 @@ class DipEdge(Thin, Alignment): @rc.setter def rc(self, arg1: float) -> None: ... -class Drift(Thick, Alignment): +class Drift(Named, Thick, Alignment): def __init__( self, ds: float, @@ -463,6 +479,7 @@ class Drift(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ A drift. @@ -488,7 +505,7 @@ class Empty(Thin): Push first the reference particle, then all other particles. """ -class ExactDrift(Thick, Alignment): +class ExactDrift(Named, Thick, Alignment): def __init__( self, ds: float, @@ -496,6 +513,7 @@ class ExactDrift(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ A Drift using the exact nonlinear map. @@ -508,7 +526,7 @@ class ExactDrift(Thick, Alignment): Push first the reference particle, then all other particles. """ -class ExactSbend(Thick, Alignment): +class ExactSbend(Named, Thick, Alignment): def __init__( self, ds: float, @@ -518,6 +536,7 @@ class ExactSbend(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> 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. @@ -544,7 +563,7 @@ class ExactSbend(Thick, Alignment): @phi.setter def phi(self, arg1: float) -> None: ... -class Kicker(Thin, Alignment): +class Kicker(Named, Thin, Alignment): def __init__( self, xkick: float, @@ -553,6 +572,7 @@ class Kicker(Thin, Alignment): dx: float = 0, dy: float = 0, rotation: float = 0, + name: str | None = None, ) -> None: """ A thin transverse kicker element. Kicks are for unit "dimensionless" or in "T-m". @@ -600,6 +620,7 @@ class KnownElementsList: | ExactDrift | ExactSbend | Kicker + | Marker | Multipole | NonlinearLens | Programmable @@ -634,6 +655,7 @@ class KnownElementsList: | ExactDrift | ExactSbend | Kicker + | Marker | Multipole | NonlinearLens | Programmable @@ -669,6 +691,7 @@ class KnownElementsList: | ExactDrift | ExactSbend | Kicker + | Marker | Multipole | NonlinearLens | Programmable @@ -706,7 +729,20 @@ class KnownElementsList: Return and remove the last element of the list. """ -class Multipole(Thin, Alignment): +class Marker(Named, Thin): + def __init__(self, arg0: str) -> None: + """ + This named element does nothing. + """ + def __repr__(self) -> str: ... + def push( + self, pc: impactx.impactx_pybind.ImpactXParticleContainer, step: int = 0 + ) -> None: + """ + Push first the reference particle, then all other particles. + """ + +class Multipole(Named, Thin, Alignment): def __init__( self, multipole: int, @@ -715,6 +751,7 @@ class Multipole(Thin, Alignment): dx: float = 0, dy: float = 0, rotation: float = 0, + name: str | None = None, ) -> None: """ A general thin multipole element. @@ -748,7 +785,18 @@ class Multipole(Thin, Alignment): @multipole.setter def multipole(self, arg1: float) -> None: ... -class NonlinearLens(Thin, Alignment): +class Named: + @property + def has_name(self) -> bool: ... + @property + def name(self) -> str: + """ + segment length in m + """ + @name.setter + def name(self, arg1: str) -> None: ... + +class NonlinearLens(Named, Thin, Alignment): def __init__( self, knll: float, @@ -756,6 +804,7 @@ class NonlinearLens(Thin, Alignment): dx: float = 0, dy: float = 0, rotation: float = 0, + name: str | None = None, ) -> None: """ Single short segment of the nonlinear magnetic insert element. @@ -782,8 +831,8 @@ class NonlinearLens(Thin, Alignment): @knll.setter def knll(self, arg1: float) -> None: ... -class PRot(Thin): - def __init__(self, phi_in: float, phi_out: float) -> None: +class PRot(Named, Thin): + def __init__(self, phi_in: float, phi_out: float, name: str | None = None) -> None: """ An exact pole-face rotation in the x-z plane. Both angles are in degrees. """ @@ -809,10 +858,12 @@ class PRot(Thin): @phi_out.setter def phi_out(self, arg1: float) -> None: ... -class Programmable: +class Programmable(Named): ds: float nslice: int - def __init__(self, ds: float = 0.0, nslice: int = 1) -> None: + def __init__( + self, ds: float = 0.0, nslice: int = 1, name: str | None = None + ) -> None: """ A programmable beam optics element. """ @@ -865,7 +916,7 @@ class Programmable: @threadsafe.setter def threadsafe(self, arg1: bool) -> None: ... -class Quad(Thick, Alignment): +class Quad(Named, Thick, Alignment): def __init__( self, ds: float, @@ -874,6 +925,7 @@ class Quad(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ A Quadrupole magnet. @@ -893,7 +945,7 @@ class Quad(Thick, Alignment): @k.setter def k(self, arg1: float) -> None: ... -class RFCavity(Thick, Alignment): +class RFCavity(Named, Thick, Alignment): def __init__( self, ds: float, @@ -907,6 +959,7 @@ class RFCavity(Thick, Alignment): rotation: float = 0, mapsteps: int = 1, nslice: int = 1, + name: str | None = None, ) -> None: """ An RF cavity. @@ -947,7 +1000,7 @@ class RFCavity(Thick, Alignment): @phase.setter def phase(self, arg1: float) -> None: ... -class Sbend(Thick, Alignment): +class Sbend(Named, Thick, Alignment): def __init__( self, ds: float, @@ -956,6 +1009,7 @@ class Sbend(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ An ideal sector bend. @@ -975,7 +1029,7 @@ class Sbend(Thick, Alignment): @rc.setter def rc(self, arg1: float) -> None: ... -class ShortRF(Thin, Alignment): +class ShortRF(Named, Thin, Alignment): def __init__( self, V: float, @@ -984,6 +1038,7 @@ class ShortRF(Thin, Alignment): dx: float = 0, dy: float = 0, rotation: float = 0, + name: str | None = None, ) -> None: """ A short RF cavity element. @@ -1017,7 +1072,7 @@ class ShortRF(Thin, Alignment): @phase.setter def phase(self, arg1: float) -> None: ... -class SoftQuadrupole(Thick, Alignment): +class SoftQuadrupole(Named, Thick, Alignment): def __init__( self, ds: float, @@ -1029,6 +1084,7 @@ class SoftQuadrupole(Thick, Alignment): rotation: float = 0, mapsteps: int = 1, nslice: int = 1, + name: str | None = None, ) -> None: """ A soft-edge quadrupole. @@ -1055,7 +1111,7 @@ class SoftQuadrupole(Thick, Alignment): @mapsteps.setter def mapsteps(self, arg1: int) -> None: ... -class SoftSolenoid(Thick, Alignment): +class SoftSolenoid(Named, Thick, Alignment): def __init__( self, ds: float, @@ -1068,6 +1124,7 @@ class SoftSolenoid(Thick, Alignment): rotation: float = 0, mapsteps: int = 1, nslice: int = 1, + name: str | None = None, ) -> None: """ A soft-edge solenoid. @@ -1101,7 +1158,7 @@ class SoftSolenoid(Thick, Alignment): @unit.setter def unit(self, arg1: float) -> None: ... -class Sol(Thick, Alignment): +class Sol(Named, Thick, Alignment): def __init__( self, ds: float, @@ -1110,6 +1167,7 @@ class Sol(Thick, Alignment): dy: float = 0, rotation: float = 0, nslice: int = 1, + name: str | None = None, ) -> None: """ An ideal hard-edge Solenoid magnet. @@ -1129,7 +1187,7 @@ class Sol(Thick, Alignment): @ks.setter def ks(self, arg1: float) -> None: ... -class TaperedPL(Thin, Alignment): +class TaperedPL(Named, Thin, Alignment): def __init__( self, k: float, @@ -1138,6 +1196,7 @@ class TaperedPL(Thin, Alignment): dx: float = 0, dy: float = 0, rotation: float = 0, + name: str | None = None, ) -> None: """ A thin nonlinear plasma lens with transverse (horizontal) taper @@ -1213,9 +1272,15 @@ class Thin: number of slices used for the application of space charge """ -class ThinDipole(Thin, Alignment): +class ThinDipole(Named, Thin, Alignment): def __init__( - self, theta: float, rc: float, dx: float = 0, dy: float = 0, rotation: float = 0 + self, + theta: float, + rc: float, + dx: float = 0, + dy: float = 0, + rotation: float = 0, + name: str | None = None, ) -> None: """ A thin kick model of a dipole bend. diff --git a/src/python/impactx/madx_to_impactx.py b/src/python/impactx/madx_to_impactx.py index 56a8881b9..59c1da1bb 100644 --- a/src/python/impactx/madx_to_impactx.py +++ b/src/python/impactx/madx_to_impactx.py @@ -66,22 +66,27 @@ def lattice(parsed_beamline, nslice=1): # print(d) if d["type"] in [k.casefold() for k in list(madx_to_impactx_dict.keys())]: if d["type"] == "drift": - impactx_beamline.append(elements.Drift(ds=d["l"], nslice=nslice)) + impactx_beamline.append( + elements.Drift(name=d["name"], ds=d["l"], nslice=nslice) + ) elif d["type"] == "quadrupole": impactx_beamline.append( - elements.Quad(ds=d["l"], k=d["k1"], nslice=nslice) + elements.Quad(name=d["name"], ds=d["l"], k=d["k1"], nslice=nslice) ) elif d["type"] == "sbend": impactx_beamline.append( - elements.Sbend(ds=d["l"], rc=d["l"] / d["angle"], nslice=nslice) + elements.Sbend( + name=d["name"], ds=d["l"], rc=d["l"] / d["angle"], nslice=nslice + ) ) elif d["type"] == "solenoid": impactx_beamline.append( - elements.Sol(ds=d["l"], ks=d["ks"], nslice=nslice) + elements.Sol(name=d["name"], ds=d["l"], ks=d["ks"], nslice=nslice) ) elif d["type"] == "dipedge": impactx_beamline.append( elements.DipEdge( + name=d["name"], psi=d["e1"], rc=1.0 / d["h"], # MAD-X is using half the gap height @@ -92,14 +97,21 @@ def lattice(parsed_beamline, nslice=1): elif d["type"] == "kicker": impactx_beamline.append( elements.Kicker( + name=d["name"], xkick=d["hkick"], ykick=d["vkick"], ) ) elif d["type"] == "monitor": if d["l"] > 0: - impactx_beamline.append(elements.Drift(ds=d["l"], nslice=nslice)) - impactx_beamline.append(elements.BeamMonitor("monitor", backend="h5")) + impactx_beamline.append( + elements.Drift( + name=d["name"] + "_drift", ds=d["l"], nslice=nslice + ) + ) + impactx_beamline.append( + elements.BeamMonitor(name="monitor", backend="h5") + ) # TODO: use name=d["name"] ? else: raise NotImplementedError( "The beamline element named ", diff --git a/tests/python/test_dataframe.py b/tests/python/test_dataframe.py index 42dc0bb4c..db73ab530 100644 --- a/tests/python/test_dataframe.py +++ b/tests/python/test_dataframe.py @@ -57,11 +57,11 @@ def test_df_pandas(save_png=True): # init accelerator lattice fodo = [ - elements.Drift(0.25), - elements.Quad(1.0, 1.0), - elements.Drift(0.5), - elements.Quad(1.0, -1.0), - elements.Drift(0.25), + elements.Drift(name="d1", ds=0.25), + elements.Quad(name="q1", ds=1.0, k=1.0), + elements.Drift(name="d2", ds=0.5), + elements.Quad(name="q2", ds=1.0, k=-1.0), + elements.Drift(name="d3", ds=0.25), ] sim.lattice.extend(fodo) diff --git a/tests/python/test_impactx.py b/tests/python/test_impactx.py index d0b086a59..871746770 100755 --- a/tests/python/test_impactx.py +++ b/tests/python/test_impactx.py @@ -112,11 +112,11 @@ def test_impactx_nofile(): # init accelerator lattice fodo = [ - elements.Drift(0.25), - elements.Quad(1.0, 1.0), - elements.Drift(0.5), - elements.Quad(1.0, -1.0), - elements.Drift(0.25), + elements.Drift(name="d1", ds=0.25), + elements.Quad(name="q1", ds=1.0, k=1.0), + elements.Drift(name="d2", ds=0.5), + elements.Quad(name="q2", ds=1.0, k=-1.0), + elements.Drift(name="d3", ds=0.25), ] # assign a fodo segment # sim.lattice = fodo @@ -127,7 +127,7 @@ def test_impactx_nofile(): # add 2 more drifts for i in range(4): - sim.lattice.append(elements.Drift(0.25)) + sim.lattice.append(elements.Drift(name="d" + str(4 + i), ds=0.25)) print(sim.lattice) print(len(sim.lattice)) @@ -158,7 +158,7 @@ def test_impactx_noparticles(): # particle bunch: init intentionally missing # init accelerator lattice - sim.lattice.append(elements.Drift(0.5)) + sim.lattice.append(elements.Drift(ds=0.5)) with pytest.raises( RuntimeError, match="No particles found. Cannot run evolve without a beam." @@ -225,7 +225,7 @@ def test_impactx_resting_refparticle(): ): sim.add_particles(bunch_charge=0.0, distr=gaussian, npart=10) - sim.lattice.append(elements.Drift(0.25)) + sim.lattice.append(elements.Drift(ds=0.25)) with pytest.raises( RuntimeError, diff --git a/tests/python/test_particle_tiles.py b/tests/python/test_particle_tiles.py index da7f2d40f..4460530e8 100644 --- a/tests/python/test_particle_tiles.py +++ b/tests/python/test_particle_tiles.py @@ -50,11 +50,11 @@ def test_particle_tiles(): # init accelerator lattice fodo = [ - elements.Drift(0.25), - elements.Quad(1.0, 1.0), - elements.Drift(0.5), - elements.Quad(1.0, -1.0), - elements.Drift(0.25), + elements.Drift(name="d1", ds=0.25), + elements.Quad(name="q1", ds=1.0, k=1.0), + elements.Drift(name="d2", ds=0.5), + elements.Quad(name="q2", ds=1.0, k=-1.0), + elements.Drift(name="d3", ds=0.25), ] sim.lattice.extend(fodo) diff --git a/tests/python/test_push.py b/tests/python/test_push.py index 3c4cc962a..04fde43bd 100644 --- a/tests/python/test_push.py +++ b/tests/python/test_push.py @@ -47,20 +47,26 @@ def test_element_push(): assert pc.total_number_of_particles() == npart # init accelerator lattice + drift = elements.Drift(name="drift1", ds=0.25) + assert drift.name == "drift1" + # changed my mind on the name + drift.name = "mydrift" + assert drift.name == "mydrift" + fodo = [ - elements.Drift(0.25), + drift, ] sim.lattice.extend(fodo) sim.evolve() - # Push manually through a few elements - elements.Quad(1.0, 1.0).push(pc) - elements.Drift(0.5).push(pc) - elements.Quad(1.0, -1.0).push(pc) + # Push manually through a few (unnamed) elements + elements.Quad(ds=1.0, k=1.0).push(pc) + elements.Drift(ds=0.5).push(pc) + elements.Quad(ds=1.0, k=-1.0).push(pc) # alternative formulation - push(pc, elements.Drift(0.25)) + push(pc, elements.Drift(ds=0.25)) # finalize simulation sim.finalize() diff --git a/tests/python/test_xopt.py b/tests/python/test_xopt.py index c5458576a..2862d6bf9 100644 --- a/tests/python/test_xopt.py +++ b/tests/python/test_xopt.py @@ -45,13 +45,13 @@ def build_lattice(parameters: dict, write_particles: bool) -> list: # enforce a mirror symmetry of the triplet line = [ - elements.Drift(ds=2.7, nslice=ns), - elements.Quad(ds=0.1, k=q1_k, nslice=ns), - elements.Drift(ds=1.4, nslice=ns), - elements.Quad(ds=0.2, k=q2_k, nslice=ns), - elements.Drift(ds=1.4, nslice=ns), - elements.Quad(ds=0.1, k=q1_k, nslice=ns), - elements.Drift(ds=2.7, nslice=ns), + elements.Drift("d1", ds=2.7, nslice=ns), + elements.Quad("q1", ds=0.1, k=q1_k, nslice=ns), + elements.Drift("d2", ds=1.4, nslice=ns), + elements.Quad("q2", ds=0.2, k=q2_k, nslice=ns), + elements.Drift("d3", ds=1.4, nslice=ns), + elements.Quad("q1", ds=0.1, k=q1_k, nslice=ns), + elements.Drift("d4", ds=2.7, nslice=ns), ] if write_particles: