vmecpp

From-scratch C++ and Python reimplementation of the Variational Moments Equilibrium Code (VMEC).

https://github.com/proximafusion/vmecpp

Science Score: 67.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 3 DOI reference(s) in README
  • Academic publication links
    Links to: sciencedirect.com, zenodo.org
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (14.0%) to scientific vocabulary

Keywords

fusion mhd-simulation plasma stellarator stellarators
Last synced: 6 months ago · JSON representation ·

Repository

From-scratch C++ and Python reimplementation of the Variational Moments Equilibrium Code (VMEC).

Basic Info
Statistics
  • Stars: 191
  • Watchers: 4
  • Forks: 24
  • Open Issues: 27
  • Releases: 17
Topics
fusion mhd-simulation plasma stellarator stellarators
Created over 1 year ago · Last pushed 6 months ago
Metadata Files
Readme License Citation

README.md

A dark Proxima logo in light color mode and a light one in dark color mode.

VMEC++

Ruff Code style: black MIT license Python version DOI

CI C++ core tests Publish wheels to PyPI

VMEC++ is a Python-friendly, from-scratch reimplementation in C++ of the Variational Moments Equilibrium Code (VMEC), a free-boundary ideal-MHD equilibrium solver for stellarators and tokamaks.

The original version was written by Steven P. Hirshman and colleagues in the 1980s and 1990s. The latest version of the original code is called PARVMEC and is available here.

Compared to its Fortran predecessors, VMEC++: - has a zero-crash policy and reports issues via standard Python exceptions - allows hot-restarting a run from a previous converged state (see Hot restart) - supports inputs in the classic INDATA format as well as simpler-to-parse JSON files; it is also simple to construct input objects programmatically in Python - typically runs just as fast or faster - comes with substantial documentation of its internal numerics

VMEC++ can run on a laptop, but it is a suitable component for large-scale stellarator optimization pipelines.

On the other hand, some features of the original Fortran VMEC are not available in VMEC++. See below for more details.


Table of Contents

Usage

This is a quick overview of the three main ways in which you can use VMEC++. See examples/ for some actual example scripts. Suitable input files are found in examples/data. If unsure where to start, we suggest to give the w7x case a try, which is a five-field-period stellarator case for the Wendelstein 7-X stellarator.

For example examples/force_residual_convergence.py runs fixed-boundary VMEC++ on the W7-X case and plots the convergence of the force residuals. <!-- SPHINX-END1 --> W7-X force residual convergence <!-- SPHINX-START2 -->

As a Python package

VMEC++ offers a simple Python API:

```python import vmecpp

Construct a VmecInput object, e.g. from a classic Fortran input file

vmecinput = vmecpp.VmecInput.fromfile("input.w7x") # or VMEC++'s w7x.json format

This is a normal Python object: it can be constructed and modified programmatically

vmec_input.rbc[0, 0] *= 1.1

Run VMEC++

vmecoutput = vmecpp.run(vmecinput)

Inspect the results programmatically or save them as a classic wout file

print(vmecoutput.mercier.iota) vmecoutput.wout.save("wout_w7x.nc") ```

All other output files are accessible via members of the output object called threed1_volumetrics, jxbout and mercier.

With SIMSOPT

SIMSOPT is a popular stellarator optimization framework. VMEC++ implements a SIMSOPT-friendly wrapper that makes it easy to use it with SIMSOPT.

```python import vmecpp.simsopt_compat

vmec = vmecpp.simsopt_compat.Vmec("input.w7x") print(f"Computed plasma volume: {vmec.volume()}") ```

As a command line tool

You can use VMEC++ directly as a CLI tool. In a terminal in which Python has access to the VMEC++ package:

```console

run on a given input file -> produce corresponding wout_w7x.nc

vmecpp is a python module and can be either run with python -m or directly as a script

vmecpp examples/data/input.w7x

check all options

vmecpp --help ```

As a Docker image

A pre-built Docker image is available at https://github.com/proximafusion/vmecpp/pkgs/container/vmecpp. Note that at present it is only updated occasionally.

See docker/README.md for more information and instructions on how to build a new image.

Installation

The easiest method for installing vmecpp is using pip: shell pip install vmecpp

For usage as part of MPI-parallelized SIMSOPT applications, you might want to also install MPI on your machine and pip install mpi4py.

Alternatively you can build the latest vmecpp directly from source according to the appropriate instructions below.

Ubuntu/Debian

Ubuntu 22.04 and 24.04, as well as Debian 12 are officially supported.

  1. Install required system packages: shell sudo apt-get install -y build-essential cmake libnetcdf-dev liblapack-dev libomp-dev libhdf5-dev python3-dev

  2. Install VMEC++ as a Python package (possibly after creating a dedicated virtual environment):

shell pip install git+https://github.com/proximafusion/vmecpp

The procedure will take a few minutes as it will build VMEC++ and some dependencies from source.

A common issue on Ubuntu is a build failure due to no python executable being available in PATH, since on Ubuntu the executable is called python3. When installing in a virtual environment (which is always a good idea anyways) python will be present. Otherwise the Ubuntu package python-is-python3 provides the python alias.

Arch Linux

  1. Install required system packages:

shell pacman -Sy --noconfirm python-pip gcc gcc-fortran openmp hdf5 netcdf lapack

  1. Install VMEC++ as a Python package (possibly after creating a virtual environment):

shell python -m pip install git+https://github.com/proximafusion/vmecpp

Fedora

Fedora 41 is officially supported.

  1. Install required system packages:

shell dnf install -y python3.10-devel cmake g++ gfortran libomp-devel hdf5-devel netcdf-devel lapack-devel

  1. Install VMEC++ as a Python package (possibly after creating a virtual environment):

```shell

If you are installing with MPI support, remember to source the mpi compiler first

. /etc/profile.d/modules.sh python3.10 -m pip install git+https://github.com/proximafusion/vmecpp ```

MacOS

  1. Install dependencies via Homebrew:

shell brew install python@3.10 gcc cmake ninja libomp netcdf-cxx git

  1. Install VMEC++ as a Python package (possibly after creating a virtual environment):

```shell

tell cmake where to find gfortran and gcc as they have non-standard names

export FC=$(which gfortran-14)

OpenMP headers live under a different path newer OS-X versions, so CMake can't find them

export OpenMPROOT=$(brew --prefix)/opt/libomp export HDF5ROOT=$(brew --prefix hdf5) python3.10 -m pip install git+https://github.com/proximafusion/vmecpp ```

As part of a conda environment

VMEC++ is currently not packaged for conda, but all its dependencies are and VMEC++ can be installed inside a conda environment. An example environment.yml file is provided here that can be used, after cloning the vmecpp repository, as:

```shell git clone https://github.com/proximafusion/vmecpp.git cd vmecpp

this creates a "vmecpp" conda environment

conda env create --file environment.yml

use the environment as usual

conda activate vmecpp ```

C++ build from source

After having installed the build dependencies as shown above, you can compile the C++ core of VMEC++ via CMake or Bazel. E.g. with CMake:

```shell git clone https://github.com/proximafusion/vmecpp.git cd vmecpp cmake -B build # create and configure build directory cmake --build build --parallel # build VMEC++

you can now use the vmec_standalone C++ executable to run VMEC on a VMEC++ input JSON file, e.g.

./build/vmec_standalone ./examples/data/solovev.json ```

The main C++ source code tree is located at src/vmecpp/cpp/vmecpp.

Hot restart

By passing the output of a VMEC++ run as initial state for a subsequent one, VMEC++ is initialized using the previously converged equilibrium. This can dramatically decrease the number of iterations to convergence when running VMEC++ on a configuration that is very similar to the converged equilibrium.

Example

```python import vmecpp

input = vmecpp.VmecInput.from_file("w7x.json")

Base run

output = vmecpp.run(input)

Now let's perturb the plasma boundary a little bit...

input.rbc[0, 0] *= 0.8 input.rbc[1, 0] *= 1.2

...and fix up the multigrid steps: hot-restarted runs only allow a single step

input.nsarray = input.nsarray[-1:] input.ftolarray = input.ftolarray[-1:] input.niterarray = input.niterarray[-1:]

We can now run with hot restart:

passing the previously obtained output ensures that

the run starts already close to the equilibrium, so it will take

very few iterations to converge this time!

hotrestartedoutput = vmecpp.run(input, restart_from=output) ```

Full tests and validation against the reference Fortran VMEC v8.52

When developing the C++ core, it's advisable to locally run the full C++ tests for debugging or to validate changes before submitting them. The full tests are not stored in the sources of this repo, but in a separate repo: https://github.com/proximafusion/vmecpplargecpp_tests . See the instructions there for how to run those tests locally. The CI of this repo includes those tests too.

The single-thread runtimes as well as the contents of the "wout" file produced by VMEC++ can be compared with those of Fortran VMEC v8.52. The full validation test can be found at https://github.com/proximafusion/vmecpp-validation, including a set of sensible input configurations, parameter scan values and tolerances that make the comparison pass. See that repo for more information.

Differences with respect to PARVMEC/VMEC2000

VMEC++: - reports issues via standard Python exceptions and has a zero crash policy - allows hot-restarting a run from a previous converged state (see Hot restart) - supports inputs in the classic INDATA format as well as simpler-to-parse JSON files; it is also simple to construct input objects programmatically in Python - employs the same parallelization strategy as Fortran VMEC, but VMEC++ leverages OpenMP for a multi-thread implementation rather than Fortran VMEC's MPI parallelization: as a consequence it cannot parallelize over multiple nodes - implements the iteration algorithm of Fortran VMEC 8.52, which sometimes has different convergence behavior from (PAR)VMEC 9.0: some configurations might converge with VMEC++ and not with (PAR)VMEC 9.0, and vice versa

Limitations with respect to the Fortran implementations

  • non-stellarator-symmetric terms (lasym == true) are not supported yet
  • free-boundary works only for ntor > 0 - axisymmetric (ntor = 0) free-boundary runs don't work yet
  • lgiveup/fgiveup logic for early termination of a multi-grid sequence is not implemented yet
  • lbsubs logic in computing outputs is not implemented yet
  • lforbal logic for non-variational forces near the magnetic axis is not implemented yet
  • lrfp is not implemented yet - only stellarators/Tokamaks for now
  • several profile parameterizations are not fully implemented yet:
    • gauss_trunc
    • two_power_gs
    • akima_spline
    • akima_spline_i
    • akima_spline_ip
    • cubic_spline
    • cubic_spline_i
    • cubic_spline_ip
    • pedestal
    • rational
    • nice_quadratic
    • sum_cossq_s
    • sum_cossq_sqrts
    • sum_cossq_s_free
  • some (rarely used) free-boundary-related output quantities are not implemented yet:
    • curlabel - declared but not populated yet
    • potvac - declared but not populated yet
    • xmpot - not declared yet
    • xnpot - not declared yet
  • 2D preconditioning using block-tridiagonal solver (BCYCLIC) is not implemented; neither are the associated input fields precon_type and prec2d_threshold
  • VMEC++ only computes the output quantities if the run converged
  • The Fortran version falls back to fixed-boundary computation if the mgrid file cannot be found; VMEC++ (gracefully) errors out instead.
  • The Fortran version accepts both the full path or filename of the input file as well as the "extension", i.e., the part after input.; VMEC++ only supports a valid filename or full path to an existing input file.

Roadmap

Some of the things we are planning for VMEC++'s future: - [x] free-boundary hot-restart in Python - [X] open-sourcing the full VMEC++ test suite (including the Verification&Validation part that compares wout contents) - [x] open-sourcing the source code to reproduce VMEC++'s performance benchmarks - [ ] VMEC++ usable as a C++ bazel module

Some items we do not plan to work on, but where community ownership is welcome: - [ ] packaging VMEC++ for platforms or package managers other than pip (e.g. conda, homebrew, ...) - [ ] native Windows support - [ ] ARM support - [ ] 2D preconditioner using bcyclic_plus_plus

Related repositories

License

vmecpp is distributed under the terms of the MIT license.

Owner

  • Name: proximafusion
  • Login: proximafusion
  • Kind: organization

Citation (CITATION.cff)

abstract: <p>From-scratch C++ and Python reimplementation of the Variational Moments
  Equilibrium Code (VMEC).</p>
authors:
- name: Proxima Fusion GmbH, Munich, Germany
- affiliation: Proxima Fusion GmbH, Munich, Germany
  family-names: Schilling
  given-names: Jonathan
- affiliation: Proxima Fusion GmbH, Munich, Germany
  family-names: Guiraud
  given-names: Enrico
- affiliation: Proxima Fusion GmbH, Munich, Germany
  family-names: Siska
  given-names: Veronika
cff-version: 1.2.0
date-released: '2025-02-04'
doi: 10.5281/zenodo.14800158
license:
- mit
title: VMEC++
type: software
version: 0.1.0

Issues and Pull Requests

Last synced: 6 months ago

All Time
  • Total issues: 31
  • Total pull requests: 207
  • Average time to close issues: 25 days
  • Average time to close pull requests: 3 days
  • Total issue authors: 9
  • Total pull request authors: 7
  • Average comments per issue: 0.68
  • Average comments per pull request: 1.37
  • Merged pull requests: 159
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 31
  • Pull requests: 207
  • Average time to close issues: 25 days
  • Average time to close pull requests: 3 days
  • Issue authors: 9
  • Pull request authors: 7
  • Average comments per issue: 0.68
  • Average comments per pull request: 1.37
  • Merged pull requests: 159
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • eguiraud-pf (13)
  • jurasic-pf (7)
  • jons-pf (3)
  • cianciosa (2)
  • missing-user (2)
  • ahnaf-tahmid-chowdhury (1)
  • dpanici (1)
  • krystophny (1)
  • DamienHuet (1)
Pull Request Authors
  • jurasic-pf (121)
  • jons-pf (43)
  • eguiraud-pf (35)
  • ahnaf-tahmid-chowdhury (2)
  • cianciosa (1)
  • landreman (1)
  • djs55 (1)
Top Labels
Issue Labels
bug (2) enhancement (1)
Pull Request Labels
enhancement (7) bug (2) merge-queue (1) codex (1)

Packages

  • Total packages: 1
  • Total downloads:
    • pypi 4,046 last-month
  • Total dependent packages: 0
  • Total dependent repositories: 0
  • Total versions: 15
  • Total maintainers: 1
pypi.org: vmecpp

Proxima Fusion's reimplementation of the Variational Moments Equilibrium Code (VMEC), a free-boundary ideal-MHD equilibrium solver for stellarators and Tokamaks.

  • Versions: 15
  • Dependent Packages: 0
  • Dependent Repositories: 0
  • Downloads: 4,046 Last month
Rankings
Dependent packages count: 9.5%
Average: 31.6%
Dependent repos count: 53.7%
Maintainers (1)
Last synced: 6 months ago

Dependencies

.github/workflows/docs.yaml actions
  • actions/checkout v4 composite
  • actions/deploy-pages v4 composite
  • actions/setup-python v5 composite
  • actions/upload-pages-artifact v3 composite
.github/workflows/test_bazel.yaml actions
  • actions/checkout v4 composite
.github/workflows/test_conda_env.yaml actions
  • actions/checkout v4 composite
  • actions/setup-python v5 composite
.github/workflows/tests.yaml actions
  • actions/checkout v4 composite
  • actions/setup-python v5 composite
  • pre-commit/action v3.0.1 composite
docker/Dockerfile docker
  • ubuntu 22.04 build
pyproject.toml pypi
  • beartype *
  • jaxtyping *
  • mpi4py *
  • netCDF4 *
  • numpy <2
  • pydantic *
  • simsopt *
.github/workflows/asan.yaml actions
  • actions/checkout v4 composite
.github/workflows/clang_tidy.yaml actions
  • ZedThree/clang-tidy-review v0.20.1 composite
  • actions/checkout v4 composite
.github/workflows/pypi_publish.yml actions
  • actions/checkout v4 composite
  • actions/download-artifact v4 composite
  • actions/upload-artifact v4 composite
  • pypa/cibuildwheel v2.23.0 composite
  • pypa/gh-action-pypi-publish release/v1 composite
environment.yml conda
  • _libgcc_mutex 0.1
  • _openmp_mutex 4.5
  • binutils
  • binutils_impl_linux-64 2.43
  • blas 2.123
  • blas-devel 3.9.0
  • blis 0.9.0
  • blosc 1.21.6
  • bzip2 1.0.8
  • c-ares 1.34.4
  • ca-certificates 2024.12.14
  • certifi 2024.12.14
  • cftime 1.6.4
  • eigen 3.4.0
  • gcc 14.2.0
  • gcc_impl_linux-64 14.2.0
  • gfortran 14.2.0
  • gfortran_impl_linux-64 14.2.0
  • gxx 14.2.0
  • gxx_impl_linux-64 14.2.0
  • hdf4 4.2.15
  • hdf5 1.14.3
  • kernel-headers_linux-64 5.14.0
  • keyutils 1.6.1
  • krb5 1.21.3
  • ld_impl_linux-64 2.43
  • libaec 1.1.3
  • libblas 3.9.0
  • libcblas 3.9.0
  • libcurl 8.11.1
  • libedit 3.1.20240808
  • libev 4.33
  • libffi 3.4.2
  • libgcc 14.2.0
  • libgcc-devel_linux-64 14.2.0
  • libgcc-ng 14.2.0
  • libgfortran-ng 7.5.0
  • libgfortran4 7.5.0
  • libgfortran5 14.2.0
  • libgomp 14.2.0
  • libiconv 1.17
  • libjpeg-turbo 3.0.0
  • liblapack 3.9.0
  • liblzma 5.6.3
  • libnetcdf 4.9.2
  • libnghttp2 1.64.0
  • libnsl 2.0.1
  • libsanitizer 14.2.0
  • libsqlite 3.47.2
  • libssh2 1.11.1
  • libstdcxx 14.2.0
  • libstdcxx-devel_linux-64 14.2.0
  • libstdcxx-ng 14.2.0
  • libuuid 2.38.1
  • libxcrypt 4.4.36
  • libxml2 2.13.5
  • libzip 1.11.2
  • libzlib 1.3.1
  • lz4-c 1.10.0
  • mpi4py
  • ncurses 6.5
  • netcdf-fortran 4.6.1
  • netcdf4 1.7.2
  • nlohmann_json
  • numpy 1.26.4
  • openssl 3.4.0
  • pip 24.3.1
  • python 3.10.16
  • python_abi 3.10
  • readline 8.2
  • setuptools 75.8.0
  • snappy 1.2.1
  • sysroot_linux-64 2.34
  • tk 8.6.13
  • tzdata 2024b
  • wheel 0.45.1
  • zlib 1.3.1
  • zstd 1.5.6