Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a thin dipole element #472

Merged
merged 14 commits into from
Nov 22, 2023
Prev Previous commit
Next Next commit
Update documentation.
  • Loading branch information
cemitch99 committed Nov 22, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit cedb8c7329cd18217e7ce31ab5931dcc51e07783
1 change: 1 addition & 0 deletions docs/source/usage/examples.rst
Original file line number Diff line number Diff line change
@@ -28,6 +28,7 @@ This section allows you to **download input files** that correspond to different
examples/cfbend/README.rst
examples/compression/README.rst
examples/kicker/README.rst
examples/thin_dipole/README.rst


Unit tests
7 changes: 7 additions & 0 deletions docs/source/usage/parameters.rst
Original file line number Diff line number Diff line change
@@ -509,6 +509,13 @@ Lattice Elements

* ``<element_name>.units`` (``string``) specification of units: ``dimensionless`` (default, in units of the magnetic rigidity of the reference particle) or ``T-m``

* ``thin_dipole`` for a thin dipole element.
This requires these additional parameters:

* ``<element_name>.theta`` (``float``, in degrees) dipole bend angle

* ``<element_name>.rc`` (``float``, in meters) effective radius of curvature

* ``beam_monitor`` a beam monitor, writing all beam particles at fixed ``s`` to openPMD files.
If the same element name is used multiple times, then an output series is created with multiple outputs.

9 changes: 9 additions & 0 deletions docs/source/usage/python.rst
Original file line number Diff line number Diff line change
@@ -725,6 +725,15 @@ References:
: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

.. py:class:: impactx.elements.ThinDipole(theta, rc)

A general thin dipole element.

:param theta: Bend angle (degrees)
:param rc: Effective curvature radius (meters)

Reference:
* G. Ripken and F. Schmidt, Thin-Lens Formalism for Tracking, CERN/SL/95-12 (AP), 1995.

Coordinate Transformation
-------------------------
70 changes: 70 additions & 0 deletions examples/thin_dipole/run_thin_dipole.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env python3
#
# Copyright 2022-2023 ImpactX contributors
# Authors: Axel Huebl, Chad Mitchell
# License: BSD-3-Clause-LBNL
#
# -*- coding: utf-8 -*-

import amrex.space3d as amr
from impactx import ImpactX, RefPart, distribution, elements

sim = ImpactX()

# set numerical parameters and IO control
sim.particle_shape = 2 # B-spline order
sim.space_charge = False
# sim.diagnostics = False # benchmarking
sim.slice_step_diagnostics = True

# domain decomposition & space charge mesh
sim.init_grids()

# load initial beam
kin_energy_MeV = 5.0 # reference energy
bunch_charge_C = 1.0e-9 # used with space charge
npart = 10000 # number of macro particles

# reference particle
ref = sim.particle_container().ref_particle()
ref.set_charge_qe(1.0).set_mass_MeV(938.27208816).set_kin_energy_MeV(kin_energy_MeV)

# particle bunch
distr = distribution.Waterbag(
sigmaX=1.0e-3,
sigmaY=1.0e-3,
sigmaT=0.3,
sigmaPx=2.0e-4,
sigmaPy=2.0e-4,
sigmaPt=2.0e-4,
muxpx=-0.0,
muypy=0.0,
mutpt=0.0,
)
sim.add_particles(bunch_charge_C, distr, npart)

# add beam diagnostics
monitor = elements.BeamMonitor("monitor", backend="h5")

# 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),
]
bend = 200*segment

inverse_bend = elements.ExactSbend(ds=-1.570796326794897,phi=-90.0)

sim.lattice.append(monitor)
sim.lattice.extend(bend)
sim.lattice.extend(inverse_bend)
sim.lattice.append(monitor)

# run simulation
sim.evolve()

# clean shutdown
del sim
amr.finalize()
12 changes: 12 additions & 0 deletions src/python/elements.cpp
Original file line number Diff line number Diff line change
@@ -471,6 +471,18 @@ void init_elements(py::module& m)
;
register_beamoptics_push(py_SoftQuadrupole);

py::class_<ThinDipole, elements::Thin> py_ThinDipole(me, "ThinDipole");
py_ThinDipole
.def(py::init<
amrex::ParticleReal const,
amrex::ParticleReal const>(),
py::arg("theta"), py::arg("rc"),
"A thin kick model of a dipole bend."
)
;
register_beamoptics_push(py_ThinDipole);


// free-standing push function
m.def("push", &Push,
py::arg("pc"), py::arg("element"), py::arg("step")=0,