Skip to content

Endoluminal Solver#

Standalone Python package for catheter/guidewire rod dynamics, focused on vasculature navigation.

This package is designed to run independently: it contains its own solver modules, data/config types, and runtime entry points under src/catheter_vasculature_solver.

Standalone package scope#

  • Provides GPU-accelerated XPBD/Cosserat rod simulation primitives.
  • Includes vessel-aware catheter extensions (track guidance + mesh containment).
  • Exposes an optional bridge to Newton's SolverXPBDRod backend.
  • Keeps solver logic self-contained in package modules (no cross-package imports into vasculature-digital-twin).

Package layout#

  • src/catheter_vasculature_solver/rod_data.py
  • Dataclass configuration surface: RodConfig, RodMaterialConfig, RodGeometryConfig, RodSolverConfig.
  • Runtime state container RodData with torch + Warp interop buffers.
  • src/catheter_vasculature_solver/rod_kernels.py
  • Warp kernels for prediction, constraints (stretch/shear/bend/twist), collisions, friction, and utility metrics.
  • src/catheter_vasculature_solver/rod_solver.py
  • High-level solver loop and orchestration for Newton iteration, direct solve path, and collision integration.
  • src/catheter_vasculature_solver/xpbd_rod_solver.py
  • Self-contained XPBD direct solver implementation (embedded Warp kernels, no external Newton requirement).
  • src/catheter_vasculature_solver/xcath_rod_solver.py
  • Catheter-in-vessel extensions: vessel containment paths and track-guided insertion behavior.
  • src/catheter_vasculature_solver/newton_xpbd_rod_wrapper.py
  • Optional wrapper around Newton's SolverXPBDRod when that runtime is available.

Install#

From this package directory:

pip install -e .

Optional Newton backend:

pip install -e ".[newton]"

Runtime dependencies#

  • Required: numpy, torch, warp-lang
  • Optional: newton (only for NewtonXPBDRodSolver)

If you only use XPBDRodSolver / XCathRodSolver, you do not need Newton installed.

Public API usage#

from catheter_vasculature_solver import RodConfig, XPBDRodSolver

cfg = RodConfig()
cfg.geometry.num_segments = 24
cfg.solver.newton_iterations = 4

solver = XPBDRodSolver(cfg)
for _ in range(100):
    solver.step(cfg.solver.dt)

positions = solver.positions

Vessel-aware variant:

from catheter_vasculature_solver import RodConfig, XCathRodSolver

Newton bridge variant (optional dependency):

from catheter_vasculature_solver import RodConfig, NewtonXPBDRodSolver

Inter-package integration (with vasculature-digital-twin)#

Use the digital twin package to generate patient-specific CT artifacts, then initialize solver constraints from those artifacts.

1) Generate CT cache + vessel artifacts:

vdt-preprocess-ct --nifti /path/to/ct.nii.gz --output-dir /tmp/ct_cache
vdt-segment-vessels --ct-dir /tmp/ct_cache

1) Load centerline artifacts and derive an insertion track:

import numpy as np

pts_mm = np.load("/tmp/ct_cache/centerline_points_mm.npy")  # (N, 3), millimeters
track_start = pts_mm[0] / 1000.0  # convert to meters
track_dir = pts_mm[1] - pts_mm[0]
track_dir = track_dir / (np.linalg.norm(track_dir) + 1e-12)
track_length = float(np.linalg.norm((pts_mm[-1] - pts_mm[0]) / 1000.0))

1) (Optional) Build a vessel collision mesh from the digital twin mask:

from vasculature_digital_twin.vasculature import extract_vessel_mesh

vessel_mask = np.load("/tmp/ct_cache/vessel_mask.npy")
vessel_mesh = extract_vessel_mesh(
    vessel_mask=vessel_mask,
    spacing_zyx_mm=(1.0, 1.0, 1.0),  # replace with metadata spacing for accurate scale
)

1) Run catheter simulation with vessel-aware solver:

from catheter_vasculature_solver import RodConfig, XCathRodSolver

cfg = RodConfig()
solver = XCathRodSolver(
    cfg,
    collision_mesh=vessel_mesh,
    track_start=track_start,
    track_dir=track_dir,
    track_length=track_length,
    tip_num_edges=10,
    particle_radius=0.002,
    segment_length=cfg.geometry.segment_length,
)

This integration is optional: the solver package remains fully usable without digital twin inputs.

Notes for standalone use#

  • The package follows a standard src/ Python layout and can be reused in other projects via editable install or wheel build.
  • Solver variants share the same configuration schema, so backends can be swapped without changing high-level parameter wiring.
  • The vasculature digital twin package is complementary but not required to run this solver package.