FreeGSNKE (pronounced "free-gee-snake") is a Python-based code for simulating the evolution of free-boundary tokamak plasma equilibria.
FreeGSNKE uses FreeGS4E, an LGPL-licensed fork of FreeGS, as its Grad-Shafranov equilibrium backend.
NOTE: We recommended reading this page in its entirety before attempting to install or run FreeGSNKE!
- Capabilities
- Coordinate and flux conventions
- Feature roadmap
- Getting started
- Installation
- Contributing
- References
- Funding
- License
FreeGSNKE is capable of solving both static (time-independent) and evolutive (time-dependent) free-boundary equilibrium problems. For fixed-boundary problems we recommend using FreeGS.
FreeGSNKE can solve:
| Problem Type | Objective | Example use cases |
|---|---|---|
| Static forward | Solve for the plasma equilibrium using user-defined poloidal field coil currents, passive structure currents, and plasma current density profiles. | Plasma scenario design and shape control. Equilibrium library generation (for emulation). Initial condition generation for evolutive simulations. Vitual circuit design. |
| Static inverse | Estimate poloidal field coil currents using user-defined constraints (e.g. isoflux and X-point locations) and plasma current density profiles for a desired plasma equilibrium shape. | Plasma scenario design. Optimisation of poloidal field coil or magnetic probe locations. |
| Evolutive forward | Solve simultaneously for the plasma equilibrium, the poloidal field coil (and passive structure) currents, and the total plasma current over time from an initial equilibrium using user-defined time-dependent poloidal field coil voltages and plasma current density profile parameters. | Full shot simulations (with or without control). Vertical stability analysis. |
These problems can be solved in a user-specified tokamak geometry that can include:
| Tokamak feature | Purpose | Properties | Element in image below |
|---|---|---|---|
| Active poloidal field coils | Can be assigned (voltage-driven) currents that influence plasma shape and position. | Locations, sizes (areas), wirings (series/anti-series), polarities (+1 or -1), resistivities (of coil materials), and number of windings. | Blue rectangles |
| Passive conducting structures | Can be assigned induced eddy currents that also impact plasma shape and position. In evolutive forward mode, these are solved self-consistently. | Locations, sizes, orientations (if available), and filaments (as passives can be refined if needed). | Dark grey parallelograms |
| Wall and/or limiter contours | Confines the plasma boundary (for computational purposes). | Locations; the limiter contour must lie strictly inside the equilibrium solution domain. | Solid black line |
| Magnetic diagnostic probes | Can measure the poloidal flux (fluxloops) or the magnetic field strength (pickup coils) at specified locations. | Locations (for both) and orientations (for pickup coils). | Orange diamonds (fluxloops) and brown dots/lines (pickup coils) |
Static Grad-Shafranov problems are solved using fourth-order accurate finite differences and a purpose-built Newton-Krylov method for additional stability and convergence speed (over the Picard iterations used in FreeGS). An implicit Euler method and the same Newton-Krylov solver are used to tackle the evolutive problem.
freegsnke_vs_efit_video_large.mp4
In the left panel above we show an example of a dynamic equilibrium calculated using FreeGSNKE's forward solver, simulating the flat-phase of a MAST-U plasma discharge. On the right is the sequence of EFIT equilibrium reconstructions from the actual MAST-U shot (re-plotted using FreeGSNKE). We can see clear agreement between the simulation and the reconstructions in both the plasma shape and the currents in the poloidal field coils, illustrating FreeGSNKE's accuracy. The contours represent constant poloidal flux and the different tokamak features are plotted in various colours (refer back to table above - noting magnetic probes not shown here).
FreeGSNKE inherits its magnetic sign and flux conventions from FreeGS4E (i.e. FreeGS). Internally, the poloidal flux function psi is stored in Webers per radian (Wb/rad, equivalently Webers/2pi) and B_p = grad(psi) x grad(phi) in the usual right-handed cylindrical coordinate system (R, phi, Z). The toroidal field function is F = R B_phi, and the plasma current Ip is the integral of J_phi over the poloidal cross-section.
Using the Sauter-Medvedev COCOS sign flags, these internal equations correspond to a COCOS-7-like convention: exp_Bp = 0, sigma_Bp = -1, sigma_RpZ = +1, and sigma_rhotp = +1.
The low-level cocos argument in the current FreeGS4E G-EQDSK parser is only a partial conversion helper: cocos < 10 leaves psi in Wb/rad, while cocos > 10 divides psi, simagx, and sibdry by 2pi. It does not apply the full set of sign changes required to transform arbitrary COCOS conventions. In practical terms, when importing or exporting equilibria from external tools, check both the 2pi flux scaling and the signs of psi, Ip, B_phi, F, and q. The higher-level FreeGS4E equilibrium import path should also be validated for your use case before relying on it in production workflows.
FreeGSNKE is constantly evolving and so we hope to provide users with more advanced features over time:
Short term:
- JAX-ification of the core Newton-Krylov solvers for auto-differentiability.
- Integration with the IMAS data formats.
Long term:
- Implementation of the current diffusion equation.
- Coupling with transport solvers.
- Coupling with MOOSE to quantify electromagnetic loads on tokamak structures during vertical displacement events.
Get familiar with FreeGSNKE: start with the FreeGSNKE user guide and examples below. The original FreeGS documentation provides useful background, but does not define the FreeGSNKE or FreeGS4E APIs.
After installation (see below), check out the FreeGSNKE user guide: the FreeGSNKE docs are hosted at docs.freegsnke.com, and the user guide contains several examples to get started. You can also build the documentation yourself by following the instructions in the docs/README.md file. The user guide is built from Jupyter notebooks in the examples/ directory, where you can also find more demos beyond those included in the user guide.
Refer to the documentation: once you are a bit more familiar with FreeGSNKE, have a look through the API documentation.
References: check out the references at the bottom of this page for even more detailed information about FreeGSNKE and how it is being used in the community!
Questions: for questions or queries about the code, first check the examples, then the documentation, then the references, and then the open/closed issues tab. If those sources don't answer your query, please open an issue and use the 'question' label.
FreeGSNKE can be installed using pip or built from source.
FreeGSNKE supports Python 3.10 through 3.14. Its runtime requirements are kept within the dependency envelope supported by FreeGS4E. Compatibility changes to Python or shared scientific dependencies are tested against both repositories as one coordinated stack.
The following stages describe how to set up a virtual environment and install FreeGSNKE with pip.
The recommended way to install FreeGSNKE is inside a virtual environment, for example using conda or venv. The instructions in this stage will set up a conda environment:
-
Install the latest Miniforge distribution for your operating system.
-
Create a new conda environment with:
conda create -n freegsnke python=3.10 pip
-
Activate the new environment with:
conda activate freegsnke
pip install freegsnkeFreeGS4E is a required dependency and is installed automatically.
If you are planning to develop FreeGSNKE, see the installing from source section below instead.
FreeGSNKE also interfaces with UDA, for example, to simulate past MAST-U shots. See examples 6a, 6b and 6c for more information. If you require this functionality and have the necessary privileges, follow these steps to install the required packages:
- Log into your account at https://gitlab.ukaea.uk/ and follow the instructions here to set up an SSH key to communicate with the CCFE GitLab instance.
- Establish a connection to the UKAEA VPN.
- Set up your envirnoment as in Stage 1 above, then specify the
udaextra in place of Stage 2:pip install freegsnke[uda]
- Finally, install the uda-mast package in your environment:
pip install "uda-mast @ git+ssh://git@gitlab.ukaea.uk/MAST-U/mastcodes.git@1.3.10#subdirectory=uda/python"
To install FreeGSNKE from source, set up your environment as in Stage 1 above.
Then, clone the repository:
git clone https://github.com/FusionComputingLab/freegsnke
Inside your environment, run the following from the FreeGSNKE root directory:
pip install -e ".[dev]"This will install FreeGSNKE in editable mode, including the optional development dependencies.
If you are also planning to co-develop FreeGS4E, clone the FreeGS4E repo and install in editable mode the same way by running the following in the FreeGS4E root directory (within your environment):
pip install -e ".[dev]"If the editable FreeGS4E installation reports a version satisfying FreeGSNKE's required version range, pip will retain it. Otherwise, pip may install a compatible FreeGS4E release from PyPI instead.
If you are planning to make code contributions, see the pull requests section below.
If contributing code (see below), please also install the pre-commit hooks by running the following in the root FreeGSNKE directory after (from source) installation:
pre-commit installThe hooks include formatting the code with black and sorting imports with isort.
Before opening a PR, also strip the outputs from any notebooks in examples/ that you've added or modified — CI rejects PRs where they're still present (see below), but they are not cleared automatically on every commit, so you're free to keep outputs in your local, unpushed notebooks while developing. To strip them, run (for example):
nbstripout examples/"your_notebook.ipynb"nbstripout is installed as part of the dev extra above.
We welcome contributions including issues, questions, bug fixes, and new features for FreeGSNKE (and FreeGS4E). To do any of these, the first step is to consider opening an issue on the project's homepage.
When opening an issue, please do the following:
- Double check that you have been using the latest version of the code as your issue/question/bug/feature might have been addressed in later releases.
- Search the open/closed issues to see if your issue has already been suggested/addressed.
- If the issue still persists, open a new issue and include the following information:
- a brief overview\justification of the issue/question/bug/feature.
- an explanation of the expected behaviour and the observed behaviour.
- if possible, a minimum working example for reproducibility.
- if possible, provide details of the culprit and a suggested fix.
- if possible, provide screenshots/diagrams (these are very helpful!).
When opening a pull request (PR), please do the following:
- Open the PR with a clear title and description of what changed and why.
- If the PR addresses an open issue, reference it in the description (e.g.
Closes #123). - Make sure the pre-commit hooks pass in the CI. These will run automatically when you commit if you have installed the pre-commit hooks (see above).
- Make sure the full test pytest suite passes locally (
python -m pytest -v); CI re-runs it against Python 3.10, 3.12, and 3.14. Specific tests can be run with, e.g.python -m pytest -v freegsnke/tests/test_static_solver.py. - Keep docstring coverage above the 95% threshold enforced in CI by interrogate.
- Clear the outputs of any Jupyter notebooks you've added or modified in
examples/(e.g. withnbstripout, see above) — CI checks the notebooks on the PR branch and rejects it if any still have outputs, but nothing strips them for you locally. - Update the user documentation, API documentation, and notebook examples if the PR changes FreeGSNKE's behaviour or public API.
- Note that the notebook execution checks only run once a maintainer applies the
ready-for-final-testslabel, so don't expect them to appear immediately when you open the PR.
If your bug fix or feature addition includes a change to how FreeGSNKE fundamentally works or requires a change to the API, be sure to document this appropriately in the user documentation, API documentation, and by writing/changing in the notebook examples (or perhaps a new one) where appropriate. Also be sure to fully justify why such changes are needed.
Thank you for contributing!
If you make use of FreeGSNKE, please cite our work:
@article{amorisco2024,
title = {{FreeGSNKE}: A Python-based dynamic free-boundary toroidal plasma equilibrium solver},
author = {Amorisco, N. C. and Agnello, A. and Holt, G. and Mars, M. and Buchanan, J. and Pamela, S.},
journal = {Physics of Plasmas},
volume = {31},
number = {4},
pages = {042517},
year = {2024},
doi = {10.1063/5.0188467},
}Here are a list of FreeGSNKE papers that describe or use the code:
- N. C. Amorisco et al, "FreeGSNKE: A Python-based dynamic free-boundary toroidal plasma equilibrium solver", Physics of Plasmas, 31, 042517 (2024). DOI: 10.1063/5.0188467.
- A. Agnello et al, "Emulation techniques for scenario and classical control design of tokamak plasmas", Physics of Plasmas, 31, 043091 (2024). DOI: 10.1063/5.0187822.
- K. Pentland et al, "Validation of the static forward Grad-Shafranov equilibrium solvers in FreeGSNKE and Fiesta using EFIT++ reconstructions from MAST-U", Physica Scripta, 100, 025608 (2025). DOI: 10.1088/1402-4896/ada192.
- K. Pentland et al, "Multiple solutions to the static forward free-boundary Grad-Shafranov problem on MAST-U", Nuclear Fusion (2025). DOI: 10.1088/1741-4326/adf3cc.
- P. Cavestany et al, "Real-time applicability of emulated virtual circuits for tokamak plasma shape control", 2025 IEEE Conference on Control Technology and Applications (2025). DOI: 10.1109/CCTA53793.2025.11151371.
- K. Pentland et al, "The FreeGSNKE Pulse Design Tool (FPDT): a computational framework for evolutive plasma scenario and control design", Plasma Physics and Controlled Fusion (2026). DOI:10.1088/1361-6587/ae8b29.
- A. Ross et al, "Real-time virtual circuits for plasma shape control via neural network emulators", arXiv (2026). arXiv:2605.14939.
- K. Pentland et al, "Real-time virtual circuits for plasma shape control via neural network surrogates: dynamic validation in closed-loop simulations", arXiv (2026). arXiv:2604.00781.
- M. Marshall et al, "Real-time virtual circuits for plasma shape control via neural network surrogates: integration and testing in the MAST-U PCS", arXiv (2026). arXiv:2608.26216.
- N. C. Amorisco et al, "Real-time virtual circuits for plasma shape control via neural network surrogates: experimental demonstration on MAST Upgrade", arXiv (2026). arXiv:2608.28468.
If you would like your FreeGSNKE-related paper to be added, please let us know!
This work was funded under the Fusion Computing Lab collaboration between the STFC Hartree Centre and the UK Atomic Energy Authority.
FreeGSNKE is distributed under the GNU Lesser General Public License v3.0. See the LICENSE file or the GNU website for more details.
The authors are also willing to discuss alternative licensing arrangements if required.
