Source code for cardiac_geometries.fibers.utils

import json
import shutil
from pathlib import Path
from typing import NamedTuple, Sequence

import adios4dolfinx
import dolfinx
import numpy as np
import ufl
from dolfinx.fem.petsc import LinearProblem
from packaging.version import Version

from ..utils import element2array, json_serial, space_from_string

_dolfinx_version = Version(dolfinx.__version__)


[docs] class Microstructure(NamedTuple): f0: dolfinx.fem.Function s0: dolfinx.fem.Function n0: dolfinx.fem.Function
def save_microstructure( mesh: dolfinx.mesh.Mesh, functions: Sequence[dolfinx.fem.Function], path: Path, viz_path: Path | None = None, viz: bool = True, checkpoint: bool = True, ) -> None: if len(functions) == 0: return # Save for paraview visualization if viz: if functions[0].function_space.ufl_element().family_name == "quadrature": from scifem.xdmf import XDMFFile if viz_path is None: viz_path = path.parent / "microstructure-viz.xdmf" viz_path = viz_path.with_suffix(".xdmf") viz_path.unlink(missing_ok=True) viz_path.with_suffix(".h5").unlink(missing_ok=True) with XDMFFile(viz_path, functions) as xdmf: xdmf.write(0.0) else: if viz_path is None: viz_path = path.parent / "microstructure-viz.bp" viz_path = viz_path.with_suffix(".bp") shutil.rmtree(viz_path, ignore_errors=True) try: with dolfinx.io.VTXWriter(mesh.comm, viz_path, functions, engine="BP4") as file: file.write(0.0) except RuntimeError as ex: print(f"Failed to write microstructure: {ex}") # Save with proper function space if checkpoint: from ..geometry import microstructure_path attributes = {f.name: element2array(f.ufl_element()) for f in functions} if mesh.comm.rank == 0: microstructure_path(path).write_text( json.dumps(attributes, indent=4, default=json_serial) ) for name, u in zip(("f0", "s0", "n0"), functions): adios4dolfinx.write_function(u=u, filename=path, name=name) def normalize(u): return u / np.linalg.norm(u, axis=0) def laplace( mesh: dolfinx.mesh.Mesh, ffun: dolfinx.mesh.MeshTags, endo_marker: int, epi_marker: int, function_space: str, ): V = dolfinx.fem.functionspace(mesh, ("Lagrange", 1)) u = ufl.TrialFunction(V) v = ufl.TestFunction(V) a = ufl.dot(ufl.grad(u), ufl.grad(v)) * ufl.dx L = v * dolfinx.fem.Constant(mesh, dolfinx.default_scalar_type(0.0)) * ufl.dx endo_facets = ffun.find(endo_marker) endo_dofs = dolfinx.fem.locate_dofs_topological(V, 2, endo_facets) epi_facets = ffun.find(epi_marker) epi_dofs = dolfinx.fem.locate_dofs_topological(V, 2, epi_facets) zero = dolfinx.fem.Constant(mesh, dolfinx.default_scalar_type(0.0)) one = dolfinx.fem.Constant(mesh, dolfinx.default_scalar_type(1.0)) endo_bc = dolfinx.fem.dirichletbc(zero, endo_dofs, V) epi_bc = dolfinx.fem.dirichletbc(one, epi_dofs, V) bcs = [endo_bc, epi_bc] kwargs = {} if _dolfinx_version >= Version("0.10"): kwargs["petsc_options_prefix"] = "cardiac_geometriesx_laplace" problem = LinearProblem( a, L, bcs=bcs, petsc_options={"ksp_type": "preonly", "pc_type": "lu"}, **kwargs ) uh = problem.solve() if function_space != "P_1": W = space_from_string(function_space, mesh, dim=1) t = dolfinx.fem.Function(W) if _dolfinx_version >= Version("0.10"): points = W.element.interpolation_points else: points = W.element.interpolation_points() expr = dolfinx.fem.Expression(uh, points) t.interpolate(expr) else: t = uh return t