Device Inductance¶
Tokamak core inductance matrices and flux tables.

Methods¶
| Object | Methods | Future Plans |
|---|---|---|
| Coils | - Axisymmetric filamentized & finite-difference flux and B-fields - Axisymmetric force contributions to each coil |
3D filamentized vector potential & B; finite element for B-fields near winding pack; 3D coil winding paths for non-axisymmetric coils |
| Passive Structures | - Multi-level meshed axisymmetric filamentization - Eigenmode model reduction |
Finite element for 3D effects |
| Sensors | Ideal integrated response w/ numerical integration in space for flux loops and Bpol probes | Additional sensor kinds |
| Plasma | Grad-Shafranov flux solve via tabulated Green's functions OR finite difference w/ filamentized free boundary condition calc | Rigid-body dynamics linearization |
Requirements¶
- Python 3.10-3.12 (use
pyenvto manage multiple versions) - pip
- gmsh
- Nominally installs from pip automatically. If the python bindings don't find it, install it manually
apt(linux),brew(mac) andchocolatey(windows) all have gmsh available, and the gmsh site has binaries
- libglu1 (for linux and likely mac)
- Required by gmsh and not always captured during gmsh install
- Environment capable of installing numpy, scipy, etc.
- This is only difficult on windows native
- For use on windows machines, WSL2 is recommended; Anaconda is not recommended
For local development, poetry is also required.
Installation¶
or, to do a development install with the git repo checked out,
Usage¶
The flow of information is
[Input: ODS object] -> device_inductance.DeviceInductance -> Analysis -> [Output: Grids, Matrices, & Tables]
where the ODS object must be in the format provided by the device description, which uses a subset of the full ODS format.
To quickly compute the most commonly used items,
import device_inductance
ods = device_inductance.load_default_ods()
typical_outputs = device_inductance.typical(ods, show_prog=False)
# With a computational grid spec provided, this would look like
# typical_outputs = device_inductance.typical(ods, extent, dxgrid)
# Extract values that are already calculated
mcc = typical_outputs.mcc # [H] coil mutual inductance matrix
# If needed, this also provides access to the full
# DeviceInductance for more detailed outputs
device = typical_outputs.device
In relatively minimal form, a handle to not-yet-calculated values can be obtained like
from device_inductance import DeviceInductance, load_default_ods
# Minimum input is just an ODS,
# but computational grid specs are required
# in order to generate non-empty flux tables
ods = load_default_ods()
device = DeviceInductance(ods, show_prog=False)
# Properties like this one are generated, along with their
# dependencies, the first time they are accessed.
mcc = device.coil_mutual_inductances
... # and so on
To get flux tables, we need to know the computational grid for which those tables will be generated.
from device_inductance import DeviceInductance, load_default_ods
# Set up a regular computational grid
# The extent provided here is always _bounded_ by the resulting mesh,
# but in order to use the exact specified grid resolution, the actual extent
# may be expanded.
#
# In order for plasma flux tables along the boundary to compute properly,
# the minimum R value in the grid should be larger than the grid resolution.
# However, since plasma current should not exist on the boundary, those values
# should have no effect on most calculations.
dr, dz = (0.05, 0.05) # [m] r,z grid resolution
min_extent = (dr * 2.0, 4.5, -3.0, 3.0) # [m] rmin, rmax, zmin, zmax
# This time, provide a grid spec
ods = load_default_ods()
device = DeviceInductance(ods, min_extent=min_extent, dxgrid=(dr, dz), show_prog=False)
# Get the resulting mesh
rmesh, zmesh = device.meshes
extent = device.extent # [m] Actual extent resolved when meshes are generated
# Now that we have a computational grid, we can
# calculate flux tables, which are also generated
# on first access.
psi_c = device.coil_flux_tables # [Wb/A]
... # and so on
See examples for a more detailed workflow.
Development¶
In the git repo, with the project installed locally via poetry,
will run the tests and examples with the headless AGG backend for matplotlib in order to suppress plots.
Contributing¶
Contributions consistent with the goals and anti-goals of the package are welcome.
Please make an issue ticket to discuss changes before investing significant time into a branch.
Goals
- Library-level functions and formulas
- Comprehensive documentation including literature references, assumptions, and units-of-measure
- Quantitative unit-testing of formulas
- Performance (both speed and memory-efficiency)
- Eliminate the need for databases to store the results of the computation
- Cross-platform compatibility
- Minimization of long-term maintenance overhead (both for the library, and for users of the library)
- Semantic versioning
- Automated linting and formatting tools
- Centralized CI and toolchain configuration in as few files as possible
Anti-Goals
- Fanciness that increases environment complexity, obfuscates reasoning, or introduces platform restrictions
- Brittle CI or toolchain processes that drive increased maintenance overhead
- Application-level functionality (graphical interfaces, simulation frameworks, etc)
License¶
Licensed under either of
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.