Skip to main content

High-Performance Large-Scale Cardic Electrophysiology Simulations on GPUs

Project description

TorchCor logo

GPU-accelerated cardiac electrophysiology simulation in PyTorch

TorchCor is a high-performance simulator for cardiac electrophysiology (CEP) using the finite element method (FEM) on general-purpose GPUs. Built on top of PyTorch, TorchCor delivers substantial computational acceleration for large-scale CEP simulations, with seamless integration into modern deep learning workflows and efficient handling of complex mesh geometries.

TorchCor offers:

  • 🚀 Fast, scalable CEP simulations on large and complex heart meshes
  • 🔗 Seamless integration with PyTorch and scientific machine learning workflows
  • ⚙️ Support for a wide range of ionic models and conductivity heterogeneity
  • 🔧 Fully customizable model parameters for flexible experimentation and prototyping
  • 🎯 Accurate simulation of cardiac electrical activity for research and development
  • 📈 Generation of precise local activation and repolarization time maps
  • 🩺 Simulation of clinically relevant 12-lead ECG signals via the lead-field method

🫀 Simulation Previews

Below are simulation results showcasing the electrical activation patterns over time in the left atrium and bi-ventricle.

Left Atrium simulation
3D left atrium surface mesh
Bi-ventricle simulation
3D bi-ventricle volume mesh

⚡ Performance

TorchCor is optimized for high-throughput cardiac electrophysiology simulations on large-scale meshes. The benchmarks below demonstrate its ability to efficiently scale with mesh size and leverage GPU acceleration over traditional CPU-based solvers. Performance tests were conducted using an AMD Ryzen Threadripper 3990X 64-Core Processor and the following GPUs:

  • NVIDIA Tesla V100
  • NVIDIA GeForce RTX 3090
  • NVIDIA RTX A6000
  • NVIDIA A100 80GB PCIe
  • NVIDIA H100 80GB HBM3
Performance on cubic meshes
Execution time on cubic 3D volume meshes with increasing node counts.
Performance on bi-ventricle mesh
Execution time on a bi-ventricle mesh (637,480 nodes) using various CPU cores and GPU devices.

Unlike traditional CPU-based solvers like PETSc, which rely heavily on MPI-based parallelism and incur communication overhead, TorchCor minimizes latency by exploiting GPU-local memory and massive parallelism. This leads to superior scaling on large meshes, where CPU frameworks struggle with inter-process communication and abstraction overheads, allowing a high-throughput, low-latency pipeline well-suited for time-sensitive cardiac simulations.

📦 Installation

pip install torchcor

Note: Requires PyTorch with CUDA support for GPU acceleration.

🚀 Quickstart Example

Here’s a concise example to run a simulation using the TenTusscher-Panfilov ionic model on a bi-ventricle mesh.

🧩 Mesh file:
You can download the bi-ventricle mesh from the following link:
Google Drive – Bi-ventricle Mesh

The inputs are:

  • .pts file: coordinates of the vertices
  • .elem file: connectivities of the mesh
  • .lon file: fibre orientations
  • One or more .vtx files: pacing locations

Running the following code will produce:

  • a list of membrane potentials, each saved after every 1 ms of the simulation
  • a local activation time map and a repolarisation time map

all saved in .pt file format readable by torch.load.

import torchcor as tc
from torchcor.simulator import Monodomain
from torchcor.ionic import TenTusscherPanfilov
from pathlib import Path

# Specify the GPU device for running the simulation
tc.set_device("cuda:0")
dtype = tc.float64
# The total simulation duration (ms)
simulation_time = 500
dt = 0.01

home_dir = Path.home()
mesh_dir = home_dir / "Data/ventricle/Case_1"
# Load in the ionic model. Here we use TenTusscherPanfilov for the simulation on bi-ventricle
im = TenTusscherPanfilov(cell_type="ENDO", dt=dt, dtype=dtype)
# 1. Initialise the Monodomain model
simulator = Monodomain(ionic_models=[im], T=simulation_time, dt=dt, dtype=dtype)
# 2. Load in the mesh files (.pts .elem .lon)
simulator.load_mesh(path=mesh_dir)
# 3. Specify the conductivity for each region
simulator.add_conductivity([34, 35], il=0.5272, it=0.2076, el=1.0732, et=0.4227)
simulator.add_conductivity([44, 45, 46], il=0.9074, it=0.3332, el=0.9074, et=0.3332)
# 4. Specify the locations where stimulation is applied
simulator.add_stimulus(mesh_dir / "LV_sf.vtx", start=0.0, duration=1.0, intensity=100)
simulator.add_stimulus(mesh_dir / "LV_pf.vtx", start=0.0, duration=1.0, intensity=100)
simulator.add_stimulus(mesh_dir / "LV_af.vtx", start=0.0, duration=1.0, intensity=100)
simulator.add_stimulus(mesh_dir / "RV_sf.vtx", start=5.0, duration=1.0, intensity=100)
simulator.add_stimulus(mesh_dir / "RV_mod.vtx", start=5.0, duration=1.0, intensity=100)

# 5. Start the simulation
snapshot_interval = 1
Vm = simulator.solve(a_tol=1e-5,              # absolute tolerance
                     r_tol=1e-5,              # relative tolerance
                     max_iter=100,            # maximum number of iterations for each CG calculation
                     snapshot_interval=snapshot_interval,     # save the solution after every 1 ms
                     verbose=True,
                     result_path="./biventricle")  # the folder in which the results are saved

# POSTPROCESSING: 
ATs = simulator.compute_activation_map(Vm=Vm, 
                                       snapshot_interval=snapshot_interval, 
                                       threshold=0)
print("ATs: ", ATs.min().item(), ATs.cpu().max().item(), flush=True)
RTs = simulator.compute_repolarization_map(Vm=Vm, 
                                           snapshot_interval=snapshot_interval, 
                                           threshold=-70)
print("RTs: ", RTs.min().item(), RTs.cpu().max().item(), flush=True)

simulator.vm_to_vtk(Vm=Vm, step=10)

🩺 12-Lead ECG via the Lead-Field Method

TorchCor reconstructs the clinical 12-lead ECG directly from a cardiac simulation using the lead-field (reciprocity) method on a coupled heart–torso mesh. Each electrode's lead field is precomputed with a single elliptic solve; the entire ECG time series then follows from one matrix–vector product with the transmembrane potential Vm, so evaluating the ECG over a whole beat is effectively free.

TorchCor simulated 12-lead ECG
Simulated 12-lead ECG from a full heart–torso model, reconstructed with the lead-field reciprocity method.

import torch
from torchcor.ecg import LeadField

# Coupled heart–torso mesh; precompute one lead field per electrode
lf = LeadField(torso_mesh_dir, heart_mesh_dir,
               device=torch.device("cuda:0"), dtype=torch.float64)

# Passive torso/organ conductivities (S/m) + anisotropic bidomain heart conductivities
lf.add_torso_conductivity([10, 11, 12], g=0.6667)
lf.add_heart_conductivity([24, 25], il=0.5272, it=0.2076, el=1.0732, et=0.4227)
lf.build()

# Electrodes (V1–V6, RA, LA, RL, LL); one elliptic solve per lead
lf.load_electrodes("electrodes/lf_src.vtx")
lf.precompute_all()

# Vm: (T, N_heart) from the EP simulation  ->  dict of the 12 standard leads
ecg = lf.compute_12lead(Vm)

A complete heart → torso → 12-lead pipeline is provided in torchcor/demo/ecg_12lead.py.

🐳 Docker Support

For a GPU-enabled Docker setup to run TorchCor without installing dependencies on your host system, please see the docker/ folder.

📖 Citation

If you use TorchCor in academic work, please consider citing:

@article{zhou2026torchcor,
  title={TorchCor: High-performance cardiac electrophysiology simulations with the finite element method on GPUs},
  author={Zhou, Bei and Balmus, Maximilian and Corrado, Cesare and Cicci, Ludovica and Qian, Shuang and Niederer, Steven A},
  journal={SoftwareX},
  volume={33},
  pages={102521},
  year={2026},
  publisher={Elsevier}
}

👩‍💻 Contributors

TorchCor is developed and maintained by Bei Zhou, Maximilian Balmus, Cesare Corrado, Shuang Qian, and Steven A. Niederer​ in the Cardiac Electro-Mechanics Research Group (CEMRG) at Imperial College London.

We welcome contributions from the community! Feel free to open issues or submit pull requests.

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

torchcor-1.0.2.tar.gz (158.2 kB view details)

Uploaded Source

Built Distribution

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

torchcor-1.0.2-py3-none-any.whl (177.5 kB view details)

Uploaded Python 3

File details

Details for the file torchcor-1.0.2.tar.gz.

File metadata

  • Download URL: torchcor-1.0.2.tar.gz
  • Upload date:
  • Size: 158.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.6

File hashes

Hashes for torchcor-1.0.2.tar.gz
Algorithm Hash digest
SHA256 1d7f9f0ba36e72698dc5bba55ea4ae95927b7ea7cfc7e0225f3e37f55e1f775f
MD5 8fdf5f76ebc988c085521bf527af6eed
BLAKE2b-256 8bc9f28defdf503b7bcb1e584af6ed4015c2a0ae3509343a359ac9c8dab37483

See more details on using hashes here.

File details

Details for the file torchcor-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: torchcor-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 177.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.6

File hashes

Hashes for torchcor-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 7b7e5e89e135e5802518d50bab87ffa282ebbf554926857e2678af9fd1bb36b5
MD5 579cbf4fd61c662f796a90611abdcefc
BLAKE2b-256 b68006ce15625874972e6c64e6c568e89d1113897ef8da1a198f7a621870816a

See more details on using hashes here.

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