Test artery generation & simulation setup

Builds a parametric test artery around an already-skeletonised stent, warps the stent onto it, checks the mixed-dimensional coupling assumptions, and — if they hold — writes a runnable 4C input.

This is a smoke test of the whole chain, not the physics of the reference papers: the artery uses a placeholder StVenantKirchhoff material, coupling is tied meshtying rather than true contact, and the balloon is a simplified radial point force.

# "sphinx_gallery" renders each Plotly figure as a self-contained text/html
# output (plotly.js loaded from CDN, no dependency on a running kernel), so
# the inline 3D view below also renders interactively on the docs website.
import plotly.io as pio
pio.renderers.default = "sphinx_gallery"
from stentfit import Stent, Artery, Simulation

STENT_NAME    = "stent01"
STENT_DIR     = f'/Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/stent_skeleton/{STENT_NAME}'
SIM_INPUT_DIR = f'/Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation'

stent = Stent.load(STENT_DIR, stent_name=STENT_NAME)
artery = Artery(
    stent,
    artery_type="curved",      # "straight" | "curved" | "s_bend"
    inner_margin=0.5,          # extra clearance [mm] between stent and artery inner wall
    wall_thickness=0.5,        # artery wall thickness [mm] (0 = lumen surface only)
    noise_amplitude=0.05,      # fractional wall roughness (0 = smooth pipe)
    noise_seed=0,
    bend_angle_deg=180.0,      # only used by "curved" / "s_bend"
    mesh_type="HEX8",          # "TET4" | "TET10" | "HEX8"
    artery_youngs=2.0,         # wall Young's modulus [MPa]
)
sim = Simulation(
    stent, artery, SIM_INPUT_DIR,

    # Stent beam material and discretisation
    stent_youngs=2.0e5,
    stent_poisson=0.3,
    stent_density=0.0,
    beam_class_label="Beam3rHerm2Line3",

    # Element sizing, both relative to the stent's strut thickness:
    # solid element = strut * factor_solid
    # beam element  = strut * factor_solid * factor_beam
    factor_solid=1.5,
    factor_beam=1.2,

    # Load stepping
    n_steps=10,                # quasi-static steps (force ramps 0 -> full)
    expansion_force=1e-4,      # radial outward force per stent node [N]
)

# One call: align stent → mesh artery solid → assemble → check coupling → write input.
sim.setup()

'''# Or: step by step
sim.align()          # beam mesh + warp onto the centreline
sim.mesh_artery()    # GMSH solid -> artery_solid.4C.yaml
sim.assemble()       # tie beams to the lumen surface
sim.check_coupling() # pass/fail table
sim.write_input()    # only once the checks pass'''
[resume] loading point cloud from /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/stent_skeleton/stent01/ring_points.csv ...
[resume] restored 10 per-ring 2D skeletons + 1,824,400 surface points. Ready for the manual-edit step.
Artery type      : curved
Artery radius    : 2.072 mm (lumen)
Wall thickness   : 0.500 mm  (outer radius 2.572 mm)
Noise amplitude  : 0.05 (5% of radius)  seed=0
Bend angle       : 180.0 deg
Bend radius      : 7.78 mm  (arc = 24.43 mm)
Arc length       : 27.14 mm  (stent 18.09 mm = 67% of artery)
Centreline       : 150 points  bounds [0. 0. 0.] → [15.55  0.    9.13]
Mesh             : 19,204 vertices  38,400 faces  watertight=True

Stent features
--------------
Loaded stent result from : /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/stent_skeleton/stent01
Centreline direction     : [1.e-04 1.e+00 0.e+00]
length          :   18.094 mm
diameter        :    3.152 mm
r_outer         :    1.572 mm
strut_thickness :    0.107 mm
z range         : [-9.048, 9.045] mm
sampled points  : 1,824,400

 Stent Meshing and Alignment
--------------

Meshed 135/135 curves (0 skipped) into a 1D beam mesh:
  2,167 nodes, 1,016 Beam3rHerm2Line3 elements
  cross-section radius 0.0536 mm, target element length 0.1931 mm
[saved] /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/stent_warped.4C.yaml

 Test_Artery Meshing
--------------
[gmsh] artery wall meshed (HEX8): r_inner=2.072 r_outer=2.572 arc length=27.140 mm  (element size 0.161 mm)
[gmsh] 59,842 nodes, 44,616 HEX8 elements  noise=0.05, warped onto centreline
[gmsh] surface node sets: lumen=14960 inlet=352 outlet=352
[saved] /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/artery_solid.4C.yaml

 Assembly of Stent and Test_Artery
--------------
[import] solid: 59,842 nodes, 44,616 elements, 3 surface set(s)
[assemble] coupling id 0: 1,016 beam elements <-> lumen surface (BoundaryCondition.beam_to_solid_surface_meshtying)
[assemble] combined mesh: 62,009 nodes, 45,632 elements
[saved] /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/artery_stent.4C.yaml
Wrote assembled beam-to-solid 4C input file -> /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/artery_stent.4C.yaml
Next: materials (HGO-C artery), boundary conditions, expansion driver, solver, run 4C.

 Paraview
[vtk] /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/artery_stent_mesh_beam.vtu
[vtk] /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/artery_stent_mesh_solid.vtu
Open the .vtu files in ParaView to inspect the meshes.

Mixed-dimensional coupling assumption check
-------------------------------------------
  [PASS] stiffness                    E_beam/E_solid = 100000.0 (>= 10.0) - beam is much stiffer than the solid
  [PASS] solid_size_vs_beam_diameter  L_solid/D_beam = 1.50 (>= 1) - solid element >= beam cross-section diameter
  [PASS] element_length_ratio         L_beam/L_solid = 1.23 - in the optimal 1-6 band
  => ALL CHECKS PASSED
[saved] /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/stent_artery_view.html
[sim] static smoke test: 10 steps, radial expansion force 0.0001 N ramped over 1,151 stent nodes
[sim] BCs: artery inlet+outlet fixed, one stent node pinned; coupling = beam-to-solid meshtying (tied)
[saved] /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/simulation.4C.yaml
[sim] schema-validated. Run in 4C on Linux: set BEAMME_FOUR_C_EXE and launch 4C on this file.

Simulation input ready -> /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/simulation.4C.yaml
'# Or: step by step\nsim.align()          # beam mesh + warp onto the centreline\nsim.mesh_artery()    # GMSH solid -> artery_solid.4C.yaml\nsim.assemble()       # tie beams to the lumen surface\nsim.check_coupling() # pass/fail table\nsim.write_input()    # only once the checks pass'

Results

setup() gates the simulation input on the coupling checks — if any fails, everything up to the assembled mesh is still written, so you can retune the element sizes and moduli and try again.

print(f"beam elements  : {len(sim.beam_mesh.elements):,}")
print(f"total elements : {len(sim.full_mesh.elements):,}")
print(f"coupling       : {'PASSED' if sim.coupling_report['all_passed'] else 'FAILED'}")
print(f"solid element  : {sim.solid_element_size:.4f} mm")
print(f"beam element   : {sim.beam_element_size:.4f} mm")
print(f"artery solid   : {sim.artery.solid_yaml}")

for path in sorted(sim.sim_input_dir.glob("*.4C.yaml")):
    print(f"  {path.name:26s} {path.stat().st_size / 1e6:8.2f} MB")
beam elements  : 1,016
total elements : 45,632
coupling       : PASSED
solid element  : 0.1609 mm
beam element   : 0.1931 mm
artery solid   : /Users/vural/Desktop/RWTH - SiSc/Projects/Github/stentFIT/examples/data/output/simulation/artery_solid.4C.yaml
  artery_solid.4C.yaml           8.09 MB
  artery_stent.4C.yaml           8.58 MB
  simulation.4C.yaml             8.84 MB
  stent_warped.4C.yaml           0.42 MB