stentfit.simulation

Classes

Simulation

A mixed-dimensional beam-to-solid simulation setup for one stent and artery.

Functions

_radial_directions(→ numpy.ndarray)

Find each point's outward radial direction relative to a centreline.

Module Contents

stentfit.simulation._radial_directions(points: numpy.ndarray, artery_cl: numpy.ndarray) numpy.ndarray

Find each point’s outward radial direction relative to a centreline.

For each point, the nearest centreline point is found (KD-tree), and the vector from that centreline point to the point has its tangent component projected out — leaving only the component perpendicular to the centreline, normalised to a unit vector. Used to point the balloon expansion force straight out from the artery’s local axis at each stent node, however the artery bends.

Parameters:
  • points(n, 3) points to find the radial direction at.

  • artery_cl – Artery centreline points.

Returns:

(n, 3) unit vectors, each point’s outward radial direction.

class stentfit.simulation.Simulation(stent: stentfit.stent.Stent, artery: stentfit.artery.Artery, sim_input_dir: str | pathlib.Path, stent_youngs: float = 200000.0, stent_poisson: float = 0.3, stent_density: float = 0.0, beam_class_label: str = 'Beam3rHerm2Line3', factor_solid: float = 1.5, factor_beam: float = 1.2, n_steps: int = 10, expansion_force: float = 0.0001)

A mixed-dimensional beam-to-solid simulation setup for one stent and artery.

Composes a Stent and an Artery into a runnable 4C input: the stent is meshed as 1D beams and warped onto the artery centreline, the artery wall is meshed as a 3D solid, the two are tied together with BeamMe’s mortar beam-to-solid coupling, and — provided the coupling assumptions hold — a static solver header, boundary conditions and a quasi-static radial expansion load are written out:

artery = Artery(stent, artery_type="curved", inner_margin=0.5)
sim = Simulation(stent, artery, "outputs/simulation/input")
sim.setup()

The artery is built first and passed in, so every artery-shape and wall-material knob lives on Artery and everything here concerns the stent, the coupling, and the load. Build both against the same stent — the constructor rejects a mismatch.

This is a smoke test, 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.

Parameters:
  • stent – The stent to deploy. Its skeletonisation must have run, since the beam mesh is built from the splines in its output folder.

  • artery – The artery to deploy into, already built by Artery. Every artery-shape and wall-material parameter lives on that object, not here.

  • sim_input_dir – Folder every generated .4C.yaml and .vtu is written into.

  • stent_youngs – Stent beam Young’s modulus, in MPa.

  • stent_poisson – Stent beam Poisson’s ratio.

  • stent_density – Stent beam material density.

  • beam_class_label – BeamMe beam element type, either 'Beam3rHerm2Line3' or 'Beam3rLine2Line2'.

  • factor_solid – Safety factor sizing the artery solid element size relative to the beam diameter.

  • factor_beam – Additional safety factor sizing the beam element length beyond factor_solid.

  • n_steps – Number of load steps for the balloon expansion ramp.

  • expansion_force – Radial point-force magnitude for the balloon expansion.

Raises:

ValueError – If artery was built for a different stent.

stent
artery
sim_input_dir
factor_solid = 1.5
stent_youngs = 200000.0
stent_poisson = 0.3
stent_density = 0.0
beam_class_label = 'Beam3rHerm2Line3'
factor_beam = 1.2
n_steps = 10
expansion_force = 0.0001
beam_mesh = None
full_mesh = None
coupling_report = None
property beam_diameter: float

The beam cross-section diameter — the stent’s strut thickness, read straight off the composed stent, in mm.

Type:

returns

property solid_element_size: float

Target artery solid element size: the beam diameter with the factor_solid safety factor applied, in mm.

Type:

returns

property beam_element_size: float

Target beam element length: the solid element size with the further factor_beam safety factor applied, in mm.

Type:

returns

print_stent_summary() None

Print the stent’s key dimensions, as a sanity check before meshing.

The values come from the live Stent object, so unlike the procedural pipeline nothing is re-read from stent_features.json / skeleton_points.csv. A stent restored with load() has no 3D skeleton in memory, so the node count is only printed when it is available.

mesh_artery() pathlib.Path

Mesh the artery wall as a 3D solid, sized to this simulation’s stent.

Thin wrapper over mesh_solid() that fills in the element size (which depends on the stent’s strut thickness, so the artery cannot work it out alone) and the output path.

Returns:

Path to the written artery_solid.4C.yaml.

align() Simulation

Mesh the straight stent as beams and warp it onto the artery centreline.

Builds the beam mesh from the stent’s fitted splines, represents the artery centreline as a BeamMe CosseratCurve, then warps the straight stent onto it — rotating the stent’s own straight axis onto the curve’s tangent, and centring the stent’s z_min/z_max mid-point on the curve’s arc mid-point. Writes stent_warped.4C.yaml.

Sets beam_mesh.

Returns:

self, so steps can be chained.

assemble(lumen_surface_index: int = 0, bc_type=None, output_filename: str = 'artery_stent.4C.yaml') Simulation

Import the artery solid and tie the stent beam mesh to it, as one 4C input.

Imports the artery’s solid .yaml (written by mesh_solid()), then couples it to beam_mesh with BeamMe’s mortar beam-to-solid method, writing the combined 4C input file. Coupling defaults to tied meshtying; pass bme.bc.beam_to_solid_surface_contact for a real deployment simulation instead of this smoke test.

Sets full_mesh.

Parameters:
  • lumen_surface_index – Index into the artery solid’s surface sets for the lumen surface the beams couple to. 0 is the lumen (DSURFACE 1, written first by the mesher).

  • bc_type – BeamMe beam-to-solid coupling type. None defaults to tied meshtying.

  • output_filename – Filename for the assembled 4C input, written into sim_input_dir.

Returns:

self, so steps can be chained.

export_paraview(output_name: str = 'artery_stent_mesh') tuple | None

Export the assembled beam+solid mesh as separate .vtu files for ParaView.

BeamMe’s write_vtk splits beams and solid elements into two files by itself; this just names them and reports their paths.

Parameters:

output_name – Base filename; _beam.vtu / _solid.vtu are appended.

Returns:

None if nothing has been assembled yet. Otherwise (beam_vtu, solid_vtu) — the paths to the two written files.

check_coupling(stiffness_ratio_min: float = 10.0, length_ratio_min: float = 1, length_ratio_max: float = 6, length_ratio_accuracy_max: float = 8.0) dict

Check the mixed-dimensional beam-to-solid coupling assumptions.

Three checks, following Steinbrecher et al., each independent:

  1. Stiffness — the beam must be much stiffer than the solid (E_beam / E_solid >= stiffness_ratio_min), since the coupling assumes the solid deforms around an effectively rigid-ish beam.

  2. Solid size vs. beam diameter — the solid element size must be at least the beam’s cross-section diameter, the spatial-resolution limit the mortar coupling is only valid above.

  3. Element length ratio — beam elements should be longer than solid elements, but not by too much: a valid band up to length_ratio_accuracy_max, and a narrower optimal band up to length_ratio_max.

The beam element length is measured from the meshed beams themselves (mean end-to-end chord), not from the requested target.

Sets coupling_report.

Parameters:
  • stiffness_ratio_min – Minimum acceptable E_beam / E_solid.

  • length_ratio_min – Lower bound of both the valid and optimal L_beam / L_solid bands.

  • length_ratio_max – Upper bound of the optimal band.

  • length_ratio_accuracy_max – Upper bound of the valid band, above which coupling accuracy degrades.

Raises:

ValueError – If the beam mesh has not been built yet.

Returns:

The report dict, one entry per check plus all_passed.

plot_overview(show: bool = True) pathlib.Path

Draw the artery surface, its centreline, and the warped stent together.

Writes stent_artery_view.html into sim_input_dir, and shows the figure inline when running in a notebook.

Parameters:

show – Try to display the figure inline as well as saving it.

Returns:

Path to the written HTML view.

write_input(out_path: str | pathlib.Path | None = None, total_time: float = 1.0, inlet_surface_index: int = 1, outlet_surface_index: int = 2, fix_stent_node: bool = True) pathlib.Path

Build a runnable, schema-validated 4C static simulation input.

Adds a static solver header and runtime VTK output, fixes the artery’s inlet and outlet surfaces (3 translational DOF, Dirichlet), and applies a quasi-static radial “balloon” expansion: a point force at each beam centreline node, directed radially outward from the artery centreline and ramped from 0 to expansion_force over n_steps by a time function. If fix_stent_node, one stent node is also pinned in translation to remove the stent’s rigid-body motion, since the radial forces alone do not constrain it.

Parameters:
  • out_path – File path the simulation input is written to. None writes simulation.4C.yaml into sim_input_dir.

  • total_time – Total simulation time for the static solver.

  • inlet_surface_index – Index into the solid’s surface geometry sets for the inlet (fixed) surface.

  • outlet_surface_index – Index into the solid’s surface geometry sets for the outlet (fixed) surface.

  • fix_stent_node – Pin one stent centreline node’s translation, to remove rigid-body motion.

Raises:

ValueError – If nothing has been assembled yet, or the imported solid is missing the inlet/outlet surface sets.

Returns:

The path written.

setup(show_plot: bool = True) Simulation

Prepare a runnable 4C input, from the stent and artery through to the load.

Chains the whole synthetic pipeline: prints the stent summary, meshes the stent as beams and warps it onto the artery centreline (align()), meshes the artery wall as a 3D solid (mesh_artery()), assembles the beam-to-solid mesh (assemble()) and exports it for ParaView (export_paraview()). It then checks the coupling assumptions (check_coupling()), shows the overview plot, and — only if those checks pass — writes the runnable input (write_input()).

Named setup rather than run on purpose: it prepares a runnable 4C input, it does not execute the analysis. Running the solve is 4C’s job, external to this package.

Parameters:

show_plot – Display the artery/stent overview figure inline.

Returns:

self, holding the meshes and the coupling report.

__repr__() str
Returns:

A short summary of how far this simulation has been set up.