Skip to main content

GPU FEM solver for the TMS E-field

Project description

cuNIBS

cuNIBS computes the electric field induced by transcranial magnetic stimulation (TMS) in a tetrahedral head model. It uses first-order finite elements, magnetic dipole coil models, CUDA kernels, and an AMGx-preconditioned linear solve. Mesh state and the AMG hierarchy remain on the GPU and are reused across coil placements.

The package is intended for computational research. It currently supports isotropic conductivity models and NVIDIA GPUs.

Numerical method

Under the magneto-quasistatic approximation, the electric field is

$$\mathbf{E} = -\nabla v - \frac{\partial \mathbf{A}}{\partial t}$$

where $v$ is the electric scalar potential and $\mathbf{A}$ is the magnetic vector potential. For piecewise constant isotropic conductivity $\sigma$, the potential satisfies

$$\nabla \cdot \left(\sigma \nabla v\right) = -\nabla \cdot \left(\sigma \frac{\partial \mathbf{A}}{\partial t}\right)$$

cuNIBS discretizes this equation with linear basis functions on tetrahedra. For tetrahedron $e$, the element matrix is

$$K_{ij}^{(e)} = V_e \sigma_e \nabla \lambda_i \cdot \nabla \lambda_j$$

The right-hand side uses the mean nodal value of $\partial\mathbf{A}/\partial t$ in each tetrahedron. One potential degree of freedom is fixed to remove the additive null space. The resulting symmetric positive-definite system is solved with preconditioned conjugate gradients and an aggregation AMG preconditioner.

The coil field is evaluated from magnetic dipoles:

$$\mathbf{A}(\mathbf{r}) = \frac{\mu_0}{4\pi} \sum_j \frac{\mathbf{m}_j \times (\mathbf{r} - \mathbf{s}_j)}{\lVert \mathbf{r} - \mathbf{s}_j \rVert^3}$$

The implementation uses float64 for stiffness assembly and the scalar potential. Placement-dependent field kernels use float32. Electric-field reconstruction accumulates $\nabla v$ in float64 before conversion to float32. The right-hand side uses a fixed per-node corner reduction order.

Installation

cuNIBS requires Python 3.12 or later and an NVIDIA GPU with a compatible driver. Install the repository with pip:

python -m pip install cunibs

The build installs the required Python packages, CUDA components, and the bundled AMGx library.

Input data

Head mesh

Subject.from_mesh reads binary Gmsh 2.2 files. The mesh must contain first-order tetrahedra and an oriented scalp surface. Coordinates are interpreted in millimetres. Volume tags select the built-in isotropic tissue conductivities. The scalp surface must use tag 1005.

Generate individualized head models with the SimNIBS CHARM pipeline:

charm subject_id T1w.nii.gz T2w.nii.gz

CHARM writes the final mesh to m2m_subject_id/subject_id.msh. A T1-weighted scan is sufficient, but a T2-weighted scan improves skull segmentation. Inspect the generated segmentation before simulation. The method is described by Puonti et al. (2020).

The conductivity assignments follow the standard SimNIBS values. The loader recognizes the following volume tags:

Tag Tissue Conductivity (S/m) Source
1 White matter 0.126 Wagner et al. (2004)
2 Gray matter 0.275 Wagner et al. (2004)
3 Cerebrospinal fluid 1.654 Wagner et al. (2004)
5 Scalp 0.465 Wagner et al. (2004)
6 Eye 0.500 Opitz et al. (2015)
7 Cortical bone 0.008 Opitz et al. (2015)
8 Cancellous bone 0.025 Opitz et al. (2015)
9 Blood 0.600 Gabriel et al. (2009)
10 Muscle 0.160 Gabriel et al. (2009)

Unsupported volume tags are removed when the mesh is loaded. Surface triangles that do not use a recognized surface tag are also removed.

Coil model

Coil.load reads the HDF5 dipole format used by the bundled coil models. Dipole positions use metres and dipole moments use A m². Models are available as constants in cunibs.coil. The package includes the 25 validated coil models reported by Drakaki et al. (2022), covering common coils from several manufacturers.

Import a SimNIBS CCD coil by converting it to HDF5:

from pathlib import Path

from cunibs.coil import Coil, encode_ccd

encode_ccd(Path("coil.ccd"), Path("coil.h5"))
coil = Coil.load("coil.h5")

Usage

from cunibs import Placement, Subject
from cunibs.coil import Coil, MAGSTIM_D70

subject = Subject.from_mesh("subject.msh")
coil = Coil.load(MAGSTIM_D70)

placement = Placement(
    center_mm=[0.0, 20.0, 80.0],
    handle_mm=[0.0, 70.0, 80.0],
    distance_mm=4.0,
)

result = subject.simulate(coil, placement, didt=1.0e6)

print(result.peak_magnE())
print(result.peak_location_mm())
print(result.focality(frac=0.5))
print(result.summary())

center_mm specifies the scalp target. handle_mm specifies a point in the positive coil-handle direction. cuNIBS projects the target onto the scalp, constructs the coil frame from the local surface normal, and applies distance_mm along the outward normal.

Pass a sequence of placements to reuse the assembled system and AMG hierarchy:

placements = [
    Placement([0.0, 20.0, 80.0], [0.0, 70.0, 80.0]),
    Placement([20.0, 0.0, 80.0], [70.0, 0.0, 80.0]),
]

results = subject.simulate(coil, placements, didt=1.0e6)

The first call builds the GPU solver state. Later calls on the same Subject reuse it.

Results

FieldResult contains:

Attribute Description Units
E Electric field per tetrahedron V/m
magnE Electric-field magnitude per tetrahedron V/m
v Electric scalar potential per node V
transform Coil-to-head affine matrix translation in mm
vols Tetrahedron volumes
tet_tags Volume tissue tags dimensionless
barycenters_mm Tetrahedron barycentres mm

The metric API reports the peak field, peak location, stimulated volume, field-weighted centre of gravity, and volume-weighted distribution statistics. Metrics can be computed over gray matter or the complete volume:

gray_matter = result.summary("gray_matter")
whole_model = result.summary("all")

Save a result and its metric inputs to HDF5:

result.save("placement.h5")

from cunibs import FieldResult

loaded = FieldResult.load("placement.h5")

Reproducibility

The solver configuration uses deterministic AMGx execution and a fixed right-hand-side reduction order. Floating-point results can still vary across GPU architectures, CUDA versions, compiler versions, and dependency versions.

Citation

No archival citation is provided yet. For reproducible academic use, cite the software by name, author, version, and Git commit, and archive the exact input mesh, coil model, and placement parameters used in the analysis.

References

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cunibs-0.1.0.tar.gz (2.2 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

cunibs-0.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (43.1 MB view details)

Uploaded CPython 3.14tmanylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

cunibs-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (43.1 MB view details)

Uploaded CPython 3.14manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

cunibs-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (43.1 MB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

cunibs-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (43.1 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

File details

Details for the file cunibs-0.1.0.tar.gz.

File metadata

  • Download URL: cunibs-0.1.0.tar.gz
  • Upload date:
  • Size: 2.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cunibs-0.1.0.tar.gz
Algorithm Hash digest
SHA256 33b5dac4c3e40b3cbda5a6fcf8aa89939167752fc719ef5c47472d3624c9dda8
MD5 fb2f959a8b7be0c0abcfc7d81dbfc63c
BLAKE2b-256 dd1b84010deb6c71a5328f295832a03d8056a6f5a057cdf66f7bddb0fa02a40d

See more details on using hashes here.

Provenance

The following attestation bundles were made for cunibs-0.1.0.tar.gz:

Publisher: wheels.yml on vcubiomag/cunibs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cunibs-0.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cunibs-0.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 942f40a228c9ff3b01624c9da53b45877e094aa56f89ce855f490f57e40a288f
MD5 3f267856286df574ef5dd81dd8e72545
BLAKE2b-256 45a9d870531162a0a77f8df8871d02935d2dcd2373ee9b480ebcbf6f76df1e41

See more details on using hashes here.

Provenance

The following attestation bundles were made for cunibs-0.1.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on vcubiomag/cunibs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cunibs-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cunibs-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 813979c147a8b5952315b58788abde3376a2e5ba12beb349a7ba3399b520c250
MD5 36a100cfb24c7d47e6f63ad66a042dd6
BLAKE2b-256 44c8876396df22b89e2bfceafad6994bba86b248a193ac73a404a375e6f18ffd

See more details on using hashes here.

Provenance

The following attestation bundles were made for cunibs-0.1.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on vcubiomag/cunibs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cunibs-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cunibs-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 fe4c35fd0af1f6260d248373adac57b602ef9644bc81c62d57030a9bbb3e70b5
MD5 19e727c828011170ae392d9a6f130e44
BLAKE2b-256 1df03c9e45a2c5b77c9e4d338a143212db8c0597bb6e05f6359ea354375717af

See more details on using hashes here.

Provenance

The following attestation bundles were made for cunibs-0.1.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on vcubiomag/cunibs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cunibs-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for cunibs-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 d995932c13a0fb200a01ec8e10d98c872067ed8c85f3c1715c375365944d8b82
MD5 86682fad87dbac57d5cebdada895c1b7
BLAKE2b-256 6c58e37c359de00f2b879c7c80371f67335bbfee0d4129d99f97eb4c21483a76

See more details on using hashes here.

Provenance

The following attestation bundles were made for cunibs-0.1.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl:

Publisher: wheels.yml on vcubiomag/cunibs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page