Skip to main content

Next generation cardiac mechanics solver based on FEniCSx

Project description

_

MIT PyPI version Test package Pre-commit Deploy static content to Pages Code style: black Create and publish a Docker image Coverage

fenicsx-pulse

fenicsx-pulse is a cardiac mechanics solver based on FEniCSx. It is a successor of pulse which is a cardiac mechanics solver based on FEniCS.

Install

You can install the library with pip

python3 -m pip install fenicsx-pulse

or with conda

conda install -c conda-forge fenicsx-pulse

Note that installing with pip requires FEniCSx already installed

We also provide a pre-built docker image with FEniCSx and fenicsx_pulse installed. You pull this image using the command

docker pull ghcr.io/finsberg/fenicsx-pulse:v0.5.2

Getting started

Here is a minimal example of how to use fenicsx-pulse to solve a simple cardiac mechanics problem.

import numpy as np
import dolfinx
import cardiac_geometries
import pulse

# Create a geometry with cardiac-geometries
geo = cardiac_geometries.mesh.lv_ellipsoid(
    outdir="geometry",
    create_fibers=True,
    fiber_space="Quadrature_6",
)
# Convert the geometry to a pulse.Geometry
geometry = pulse.HeartGeometry.from_cardiac_geometries(geo, metadata={"quadrature_degree": 6})

# Create a material model
material_params = pulse.HolzapfelOgden.transversely_isotropic_parameters()
material = pulse.HolzapfelOgden(f0=geo.f0, s0=geo.s0, **material_params)

# Define model for active contraction
Ta = pulse.Variable(dolfinx.fem.Constant(geometry.mesh, dolfinx.default_scalar_type(0.0)), "kPa")
active_model = pulse.ActiveStress(geo.f0, activation=Ta)

# Define mode for compressibility
comp_model = pulse.Incompressible()

# Assemble into a cardiac model
model = pulse.CardiacModel(
    material=material,
    active=active_model,
    compressibility=comp_model,
)

# Define boundary conditions
traction = pulse.Variable(
    dolfinx.fem.Constant(geometry.mesh, dolfinx.default_scalar_type(0.0)), "kPa"
)
neumann = pulse.NeumannBC(traction=traction, marker=geometry.markers["ENDO"][0])


def dirichlet_bc(V: dolfinx.fem.FunctionSpace):
    # Find facets for the BASE marker
    facets = geo.ffun.find(geo.markers["BASE"][0])
    # Locate degrees of freedom for the x-component (sub(0)) on these facets
    dofs = dolfinx.fem.locate_dofs_topological(V.sub(0), geo.mesh.topology.dim - 1, facets)
    # Return the Dirichlet BC object
    return [dolfinx.fem.dirichletbc(0.0, dofs, V.sub(0))]


robin_epi = pulse.RobinBC(
    value=pulse.Variable(
        dolfinx.fem.Constant(geometry.mesh, dolfinx.default_scalar_type(1e3)),
        "Pa / m",
    ),
    marker=geometry.markers["EPI"][0],
)
robin_base = pulse.RobinBC(
    value=pulse.Variable(
        dolfinx.fem.Constant(geometry.mesh, dolfinx.default_scalar_type(1e3)),
        "Pa / m",
    ),
    marker=geometry.markers["BASE"][0],
)

bcs = pulse.BoundaryConditions(neumann=(neumann,), dirichlet=(dirichlet_bc,), robin=(robin_base, robin_epi))

# Create a mechanics problem
problem = pulse.StaticProblem(
    model=model,
    geometry=geometry,
    bcs=bcs,
)
# Perform an initial solve
problem.solve()

# Create a file for storing the solution
vtx = dolfinx.io.VTXWriter(geometry.mesh.comm, "displacement.bp", [problem.u], engine="BP4")
vtx.write(0.0)

# Assign a pressure and activation and ramp them up in steps
target_pressure = 5.0  # kPa
target_activation = 5.0  # kPa
num_steps = 5
for i, (pressure, activation) in enumerate(
    zip(np.linspace(0, target_pressure, num_steps), np.linspace(0, target_activation, num_steps))
):
    traction.assign(pressure)  # kPa
    Ta.assign(activation)  # kPa
    problem.solve()
    # Save the displacement field
    vtx.write(i + 1)
vtx.close()

_

A more realistic example is visualized here:

https://github.com/user-attachments/assets/8e2f5d85-3fbf-4e30-9574-22e7f718230c

Checkout out the demos in the documentation for more examples.

Contributing

See https://finsberg.github.io/fenicsx-pulse/CONTRIBUTING.html

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

fenicsx_pulse-0.5.2.tar.gz (42.2 kB view details)

Uploaded Source

Built Distribution

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

fenicsx_pulse-0.5.2-py3-none-any.whl (45.5 kB view details)

Uploaded Python 3

File details

Details for the file fenicsx_pulse-0.5.2.tar.gz.

File metadata

  • Download URL: fenicsx_pulse-0.5.2.tar.gz
  • Upload date:
  • Size: 42.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fenicsx_pulse-0.5.2.tar.gz
Algorithm Hash digest
SHA256 97e4b97290379a2508439647b279ccf4a45bda8ce444491a86ec0281cacf8ca0
MD5 f66bd125a4951abe06135f4a48a54f65
BLAKE2b-256 694a76e0a1d733e5c4702455d915388a9f38f2d6c9383fb4feb1a5010dbc1c10

See more details on using hashes here.

Provenance

The following attestation bundles were made for fenicsx_pulse-0.5.2.tar.gz:

Publisher: pypi.yml on finsberg/fenicsx-pulse

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

File details

Details for the file fenicsx_pulse-0.5.2-py3-none-any.whl.

File metadata

  • Download URL: fenicsx_pulse-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 45.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fenicsx_pulse-0.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 d561df205d66b9fa18f3fd15a7358e77e5ffa47a214698c3d98f3edeb8f0b8be
MD5 63b2d98f5f687d166ea5b64d0a629b2f
BLAKE2b-256 95fccbcab2d4df0235d26a9b4385a3c7acad3ac7c66487532d564bbb8a2da5d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for fenicsx_pulse-0.5.2-py3-none-any.whl:

Publisher: pypi.yml on finsberg/fenicsx-pulse

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