Skip to content

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

beamtracer

Tests Static analysis Docs codecov PyPI Python

Steady ion beams in a self-consistent field: extraction of positive or negative ions from a plasma, transport through electrodes and solenoids, and charge changes of a fast beam in a gas or a plasma, in planar or cylindrical (x, r) geometry. BeamOptics converges the beam by a Vlasov iteration (solve the field, trace the beam, deposit its space charge, repeat); beamtracer.neutralizer couples the traced beam to a global model of a beam-driven plasma neutralizer (wellbalanced). The field gather and the charge deposit are Pyccel, NumPy, CUDA and Metal kernels through cunumpy. beamtracer.optimization searches over the parameters of a design (SciPy’s differential evolution, or a scan) in parallel processes, with constraints, penalised failures and a resumable record of every evaluation; its problems are an einzel lens (beamtracer.optimization.einzel) and a negative-ion beamlet (beamtracer.optimization.beamlet).

Documentation: https://max-models.github.io/beamtracer/

Install

With uv:

make install    # uv sync --extra dev, plus the pre-commit hooks

Or create and activate a Python environment (3.10 or newer) and install with pip:

python -m venv env
source env/bin/activate
pip install --upgrade pip
pip install -e .

The neutralizer extra installs wellbalanced, examples the plotting libraries of the examples, and test, docs and dev the test runner, the documentation tooling and the linters:

pip install -e ".[dev]"

A planar diode

import astropy.units as u

from beamtracer import (
    BeamOptics,
    BeamOpticsConfig,
    BeamSpecies,
    FieldBCs,
    FieldBoundaryCondition,
    GridParams,
)

neumann = FieldBoundaryCondition.neumann(0.0)
config = BeamOpticsConfig(
    grid=GridParams(num_gridpoints=(41, 21), upper_bound=(10 * u.mm, 5 * u.mm)),
    bcs_field=FieldBCs(
        x_lower=FieldBoundaryCondition.dirichlet(0.0),
        x_upper=FieldBoundaryCondition.dirichlet(-1 * u.kV),
        y_lower=neumann,
        y_upper=neumann,
    ),
    beams=[
        BeamSpecies(
            "H+",
            10 * u.A / u.m**2,
            (0.0, 0.0),
            (0.0, 5 * u.mm),
            energy="10 meV",
            num_particles=40,
        )
    ],
    diagnostic_planes=["9.9 mm"],
)
model = BeamOptics(config).run()
print(model.beam_moments(9.9e-3).current)

Every physical setting takes an astropy Quantity (5 * u.mm), a string astropy parses ("5 mm", as in a configuration file) or a bare number in its documented unit: SI, with energies and temperatures in eV (or K), masses in u and charges in e. It is converted when the setting is made, so the bare numbers upper_bound=(10e-3, 5e-3), -1000.0 and energy=0.01 are the same diode. A quantity of the wrong dimension raises.

The examples (python -m beamtracer.examples.<name>) are a planar proton extraction, a round H⁻ beamlet with its co-extracted electrons, and a D⁻ beam through a neutralizer channel.

Development

Formatting and linting use ruff, type checking pyright, run by pre-commit and in CI:

make lint     # ruff check, ruff format --check, pyright
make test     # pytest with coverage

Commit messages follow Conventional Commits; see CONTRIBUTING.md.

Build docs

The documentation in docs/ is an Astro + Starlight site: hand-written pages, the notebooks in tutorials/ executed and published as pages, and the API reference generated from the docstrings with starlight-pydocs. It needs Node 22 or newer.

make docs-install     # npm packages and the Python docs extra
make docs-notebooks   # execute tutorials/*.ipynb and convert them to pages
make docs-dev         # live preview at http://localhost:4321/beamtracer/
make docs-build       # the static site in docs/dist

Build the README

README.md is rendered from README.qmd with Quarto:

make readme

Releases

Before merging a release to main, update the version in pyproject.toml, src/beamtracer/__init__.py and CITATION.cff (including its release date), and add the release notes to CHANGELOG.md. The push to main creates a GitHub release with a vX.Y.Z tag and publishes the package to PyPI with trusted publishing (OIDC). The one-time PyPI and GitHub configuration is described in the publishing tutorial.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages