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 MADX Input Parser #214

Merged
merged 19 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions docs/source/usage/python.rst
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ Particles

Write-only: Set reference particle energy.

.. py:method:: load_file(madx_file)

Load reference particle information from a MAD-X file.

:param madx_file: file name to MAD-X file with a ``BEAM`` entry


Initial Beam Distributions
--------------------------
Expand Down Expand Up @@ -305,6 +311,25 @@ This module provides elements for the accelerator lattice.

An iterable, ``list``-like type of elements.

.. py:method:: clear()

Clear the list to become empty.

.. py:method:: extend(list)

Add a list of elements to the list.

.. py:method:: append(element)

Add a single element to the list.

.. py:method:: load_file(madx_file, nslice=1)

Load and append an accelerator lattice description from a MAD-X file.

: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.ConstF(ds, kx, ky, kt, nslice=1)

A linear Constant Focusing element.
Expand Down
26 changes: 26 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ add_impactx_test(FODO.py
examples/fodo/plot_fodo.py
)

# Python MADX: FODO Cell ######################################################
#
# copy MAD-X lattice file
file(COPY ${ImpactX_SOURCE_DIR}/examples/fodo/fodo.madx DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/FODO.MADX.py)

add_impactx_test(FODO.MADX.py
examples/fodo/run_fodo_madx.py
OFF # ImpactX MPI-parallel
ON # ImpactX Python interface
examples/fodo/analysis_fodo.py
examples/fodo/plot_fodo.py
)

# Python: MPI-parallel FODO Cell ##############################################
#
add_impactx_test(FODO.py.MPI
Expand Down Expand Up @@ -134,6 +147,19 @@ add_impactx_test(chicane.py
examples/chicane/plot_chicane.py
)

# Python MADX: Chicane ######################################################
#
# copy MAD-X lattice file
file(COPY ${ImpactX_SOURCE_DIR}/examples/chicane/chicane.madx DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/chicane.MADX.py)

add_impactx_test(chicane.MADX.py
examples/chicane/run_chicane_madx.py
OFF # ImpactX MPI-parallel
ON # ImpactX Python interface
examples/chicane/analysis_chicane.py
examples/chicane/plot_chicane.py
)

# Constant Focusing Channel ###################################################
#
add_impactx_test(cfchannel
Expand Down
17 changes: 17 additions & 0 deletions examples/chicane/chicane.madx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
beam, particle=electron, energy=5.0;

D1: drift, L=5.0058489435;
D2: drift, L=1.0;
D3: drift, L=2.0;
! TODO make this work with inline calculations
! theta=0.50037/10.35;
! inv_rho=1.0/10.35
! TODO put `angle=theta` for SBENDs and `e1=theta` for DIPEDGEs with their right sign
SB1: sbend, L=0.50037, angle=-0.04834492753623188, e1=0.000, e2=0.000, k1=0.00;
SB2: sbend, L=0.50037, angle=0.04834492753623188, e1=0.000, e2=0.000, k1=0.00;
! dipole edge elements
DIPE1: dipedge, H=-0.0966183574879227, e1=-0.048345620280243, fint=0.000, hgap=0.000, tilt=0.00;
DIPE2: dipedge, H=0.0966183574879227, e1=0.048345620280243, fint=0.000, hgap=0.000, tilt=0.00;

CHICANE: Line=(SB1,DIPE1,D1,DIPE2,SB2,D2,SB2,DIPE2,D1,DIPE1,SB1,D3);
USE, SEQUENCE = CHICANE;
54 changes: 54 additions & 0 deletions examples/chicane/run_chicane_madx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env python3
#
# Copyright 2022 ImpactX contributors
# Authors: Marco Garten, Axel Huebl, Chad Mitchell
# License: BSD-3-Clause-LBNL
#
# -*- coding: utf-8 -*-


import amrex
from impactx import ImpactX, RefPart, distribution, elements

sim = ImpactX()

# set numerical parameters and IO control
sim.set_particle_shape(2) # B-spline order
sim.set_space_charge(False)
# sim.set_diagnostics(False) # benchmarking
sim.set_slice_step_diagnostics(True)

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

# load a 5 GeV electron beam with an initial
# normalized transverse rms emittance of 1 um
bunch_charge_C = 1.0e-9 # used with space charge
npart = 10000 # number of macro particles

# reference particle
ref = sim.particle_container().ref_particle().load_file("chicane.madx")

# particle bunch
distr = distribution.Waterbag(
sigmaX=2.2951017632e-5,
sigmaY=1.3084093142e-5,
sigmaT=5.5555553e-8,
sigmaPx=1.598353425e-6,
sigmaPy=2.803697378e-6,
sigmaPt=2.000000000e-6,
muxpx=0.933345606203060,
muypy=0.933345606203060,
mutpt=0.999999961419755,
)
sim.add_particles(bunch_charge_C, distr, npart)

# design the accelerator lattice
sim.lattice.load_file("chicane.madx", nslice=25)

# run simulation
sim.evolve()

# clean shutdown
del sim
amrex.finalize()
11 changes: 11 additions & 0 deletions examples/fodo/fodo.madx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
! TODO implement handling of title
! TITLE,'FODO.MADX';
BEAM, PARTICLE=ELECTRON,ENERGY=2.0;

D1: DRIFT,L=0.25;
D2: DRIFT,L=0.50;
QF: QUADRUPOLE,L=1.0,K1=1.0;
QD: QUADRUPOLE,L=1.0,K1=-1.0;

FODO: LINE=(D1,QF,D2,QD,D1);
USE, SEQUENCE = FODO;
55 changes: 55 additions & 0 deletions examples/fodo/run_fodo_madx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env python3
#
# Copyright 2022 ImpactX contributors
# Authors: Marco Garten, Axel Huebl, Chad Mitchell
# License: BSD-3-Clause-LBNL
#
# -*- coding: utf-8 -*-


import amrex
from impactx import ImpactX, RefPart, distribution, elements

sim = ImpactX()

# set numerical parameters and IO control
sim.set_particle_shape(2) # B-spline order
sim.set_space_charge(False)
# sim.set_diagnostics(False) # benchmarking
sim.set_slice_step_diagnostics(True)

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

# load a 2 GeV electron beam with an initial
# unnormalized rms emittance of 2 nm
energy_MeV = 2.0e3 # 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().load_file("fodo.madx")

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

# design the accelerator lattice
sim.lattice.load_file("fodo.madx", nslice=25)

# run simulation
sim.evolve()

# clean shutdown
del sim
amrex.finalize()
47 changes: 28 additions & 19 deletions src/python/elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,34 @@ void init_elements(py::module& m)
return v;
}))

.def("append", [](KnownElementsList &v, KnownElements el) { v.emplace_back(el); })

.def("extend", [](KnownElementsList &v, KnownElementsList l) {
for (auto const & el : l)
v.push_back(el);
return v;
})
.def("extend", [](KnownElementsList &v, py::list l) {
for (auto const & handle : l)
{
auto el = handle.cast<KnownElements>();
v.push_back(el);
}
return v;
})

.def("clear", &KnownElementsList::clear)
.def("pop_back", &KnownElementsList::pop_back)
.def("__len__", [](const KnownElementsList &v) { return v.size(); })
.def("append", [](KnownElementsList &v, KnownElements el) { v.emplace_back(el); },
"Add a single element to the list.")

.def("extend",
[](KnownElementsList &v, KnownElementsList l) {
for (auto const & el : l)
v.push_back(el);
return v;
},
"Add a list of elements to the list.")
.def("extend",
[](KnownElementsList &v, py::list l) {
for (auto const & handle : l)
{
auto el = handle.cast<KnownElements>();
v.push_back(el);
}
return v;
},
"Add a list of elements to the list."
)

.def("clear", &KnownElementsList::clear,
"Clear the list to become empty.")
.def("pop_back", &KnownElementsList::pop_back,
"Return and remove the last element of the list.")
.def("__len__", [](const KnownElementsList &v) { return v.size(); },
"The length of the list.")
.def("__iter__", [](KnownElementsList &v) {
return py::make_iterator(v.begin(), v.end());
}, py::keep_alive<0, 1>()) /* Keep list alive while iterator is used */
Expand Down
Loading