Пример #1
0
def test_lv_regression(lv_geometry, use_krylov_solver):
    ldrb.dolfin_ldrb(
        mesh=lv_geometry.mesh,
        ffun=lv_geometry.ffun,
        markers=lv_geometry.markers,
        use_krylov_solver=use_krylov_solver,
    )
Пример #2
0
def generate_fibers(mesh, fiber_params, ffun=None):
    """
    Generate fibers on mesh based on provided parameters.
    It is not recomemmended to use this function.
    Use the `ldrb` package directly instead. This function is
    mainly used to ensure version compatability.
    """

    try:
        from ldrb import dolfin_ldrb
    except ImportError:
        msg = ('"ldrb" package not found. Please go to '
               "https://github.com/finsberg/ldrb to see how you can get it!")
        print(msg)
        raise ImportError(msg)

    if isinstance(fiber_params, dolfin.Parameters):
        p = fiber_params.to_dict()
    else:
        p = fiber_params

    angles = dict(alpha_endo_lv=p.get("fiber_angle_endo"),
                  alpha_epi_lv=p.get("fiber_angle_epi"))
    for name, a in angles.items():
        if isinstance(a, dolfin.cpp.parameter.Parameter):
            angles[name] = a.value()

    return dolfin_ldrb(mesh, ffun=ffun, **angles)
Пример #3
0
def create_fiber_fields(mesh,
                        markers,
                        ffun,
                        angles=None,
                        fiber_space='Quadrature_2'):

    if angles is None:
        angles = dict(
            alpha_endo_lv=60,  # Fiber angle on the endocardium
            alpha_epi_lv=-60,  # Fiber angle on the epicardium
            beta_endo_lv=0,  # Sheet angle on the endocardium
            beta_epi_lv=0)  # Sheet angle on the epicardium

    # Choose space for the fiber fields
    # This is a string on the form {family}_{degree}
    # fiber_space = 'Quadrature_2'
    # At all nodes
    # fiber_space = 'Lagrange_1'
    m = {
        'lv': markers.get('ENDO')[0],
        'epi': markers.get('EPI')[0],
        'base': markers.get('BASE')[0],
    }
    # Compute the microstructure
    fiber, sheet, sheet_normal = ldrb.dolfin_ldrb(mesh=mesh,
                                                  fiber_space=fiber_space,
                                                  ffun=ffun,
                                                  markers=m,
                                                  **angles)
    fiber.rename("fiber", "microstructure")
    sheet.rename("sheet", "microstructure")
    sheet_normal.rename("sheet_normal", "microstructure")
    ldrb.fiber_to_xdmf(fiber, 'lv_fiber')
    return [fiber, sheet, sheet_normal]
Пример #4
0
angles = dict(
    alpha_endo_lv=60,  # Fiber angle on the endocardium
    alpha_epi_lv=-60,  # Fiber angle on the epicardium
    beta_endo_lv=0,  # Sheet angle on the endocardium
    beta_epi_lv=0,
)  # Sheet angle on the epicardium

# Choose space for the fiber fields
# This is a string on the form {family}_{degree}
# fiber_space = 'Quadrature_2'
fiber_space = "Lagrange_1"

# Compte the microstructure
fiber, sheet, sheet_normal = ldrb.dolfin_ldrb(mesh=mesh,
                                              fiber_space=fiber_space,
                                              ffun=ffun,
                                              markers=markers,
                                              **angles)

# fiber.rename('fiber', 'fibers')
# sheet.rename('sheet', 'fibers')
# sheet_normal.rename('sheet_normal', 'fibers')
# import pulse.geometry_utils as utils

# import numpy as np
# focal = np.sqrt(1.5**2 - 0.5**2)
# sfun = utils.mark_strain_regions(mesh, foc=focal)

# df.File('sfun.pvd') << sfun

# angles['alpha_endo_lv'] = 0
Пример #5
0
def prolate_ellipsoid_geometry(
    r_short_endo: float = 7.0,
    r_short_epi: float = 10.0,
    r_long_endo: float = 17.0,
    r_long_epi: float = 20.0,
    quota_base: float = 0.0,
    psize: float = 3.0,
    ndiv: float = 1.0,
    mesh_size_factor: float = 1.0,
    fiber_params: typing.Optional[typing.Dict[str, typing.Any]] = None,
):
    fiber_params = fiber_params or {}
    fiber_params = fiber_params.copy()
    signature = hashit(
        repr(
            dict(
                r_short_endo=r_short_endo,
                r_short_epi=r_short_epi,
                r_long_endo=r_long_endo,
                r_long_epi=r_long_epi,
                quota_base=quota_base,
                psize=psize,
                ndiv=ndiv,
                mesh_size_factor=mesh_size_factor,
                fiber_params=fiber_params,
            ), ), )
    path = cachedir.joinpath(f"prolate_ellipsoid_geometry_{signature}.h5")

    if not path.is_file():
        check_ldrb()
        msh_name = Path("test.msh")
        create_benchmark_ellipsoid_mesh_gmsh(
            msh_name,
            r_short_endo=r_short_endo,
            r_short_epi=r_short_epi,
            r_long_endo=r_long_endo,
            r_long_epi=r_long_epi,
            quota_base=quota_base,
            psize=psize,
            ndiv=ndiv,
            mesh_size_factor=mesh_size_factor,
        )

        geo: HeartGeometry = gmsh2dolfin(msh_name)
        msh_name.unlink()
        ldrb_markers = {
            "base": geo.markers["BASE"][0],
            "epi": geo.markers["EPI"][0],
            "lv": geo.markers["ENDO"][0],
        }

        fiber_space = fiber_params.pop("fiber_space", "CG_1")

        fiber_sheet_system = ldrb.dolfin_ldrb(geo.mesh, fiber_space, geo.ffun,
                                              ldrb_markers, **fiber_params)
        geo.microstructure = Microstructure(
            f0=fiber_sheet_system.fiber,
            s0=fiber_sheet_system.sheet,
            n0=fiber_sheet_system.sheet_normal,
        )
        geo.save(path)
    return HeartGeometry.from_file(path)
Пример #6
0
# In the case of a BiV we do a little trick where me mark the RV as LV in order to find the longitudinal vector field. We run the  algorithm again with some different angles to get the circumferential vector field and finally take the cross product to get the radial vector field.
# (if you find a better way of doing this, please submit a PR).
#

if case == "biv":
    lv_ffun = dolfin.MeshFunction("size_t", mesh, 2)
    lv_ffun.array()[:] = ffun.array().copy()
    lv_ffun.array()[ffun.array() == markers["rv"]] = markers["lv"]
    lv_markers = markers.copy()
    lv_markers.pop("rv")

    long, _, _ = ldrb.dolfin_ldrb(
        mesh=mesh,
        fiber_space=space,
        ffun=lv_ffun,
        markers=lv_markers,
        alpha_endo_lv=-90,
        alpha_epi_lv=-90,
        beta_endo_lv=0,
        beta_epi_lv=0,
    )

    circ, _, _ = ldrb.dolfin_ldrb(
        mesh=mesh,
        fiber_space=space,
        ffun=ffun,
        markers=markers,
        alpha_endo_lv=0,
        alpha_epi_lv=0,
        beta_endo_lv=0,
        beta_epi_lv=0,
    )
Пример #7
0
def test_ldrb_without_correct_markers_raises_RuntimeError(lv_geometry):
    with pytest.raises(RuntimeError):
        ldrb.dolfin_ldrb(mesh=lv_geometry.mesh)
Пример #8
0
def create_geometry(h5name):
    """
    Create an lv-ellipsoidal mesh and fiber fields using LDRB algorithm

    An ellipsoid is given by the equation

    .. math::

        \frac{x^2}{a} + \frac{y^2}{b} + \frac{z^2}{c} = 1

    We create two ellipsoids, one for the endocardium and one
    for the epicardium and subtract them and then cut the base.
    For simplicity we assume that the longitudinal axis is in
    in :math:`x`-direction and as default the base is located
    at the :math:`x=0` plane.
    """

    # Number of subdivision (higher -> finer mesh)
    N = 13

    # Parameter for the endo ellipsoid
    a_endo = 1.5
    b_endo = 0.5
    c_endo = 0.5
    # Parameter for the epi ellipsoid
    a_epi = 2.0
    b_epi = 1.0
    c_epi = 1.0
    # Center of the ellipsoid (same of endo and epi)
    center = (0.0, 0.0, 0.0)
    # Location of the base
    base_x = 0.0

    # Create a lv ellipsoid mesh with longitudinal axis along the x-axis
    geometry = ldrb.create_lv_mesh(N=N,
                                   a_endo=a_endo,
                                   b_endo=b_endo,
                                   c_endo=c_endo,
                                   a_epi=a_epi,
                                   b_epi=b_epi,
                                   c_epi=c_epi,
                                   center=center,
                                   base_x=base_x)

    # Select fiber angles for rule based algorithm
    angles = dict(
        alpha_endo_lv=60,  # Fiber angle on the endocardium
        alpha_epi_lv=-60,  # Fiber angle on the epicardium
        beta_endo_lv=0,  # Sheet angle on the endocardium
        beta_epi_lv=0)  # Sheet angle on the epicardium

    fiber_space = 'Lagrange_1'

    # Compte the microstructure
    fiber, sheet, sheet_normal = ldrb.dolfin_ldrb(mesh=geometry.mesh,
                                                  fiber_space=fiber_space,
                                                  ffun=geometry.ffun,
                                                  markers=geometry.markers,
                                                  **angles)

    # Compute focal point
    focal = np.sqrt(a_endo**2 - (0.5 * (b_endo + c_endo))**2)
    # Make mesh according to AHA-zons
    pulse.geometry_utils.mark_strain_regions(mesh=geometry.mesh, foc=focal)

    mapper = {'lv': 'ENDO', 'epi': 'EPI', 'rv': 'ENDO_RV', 'base': 'BASE'}
    m = {mapper[k]: (v, 2) for k, v in geometry.markers.items()}

    pulse.geometry_utils.save_geometry_to_h5(
        geometry.mesh, h5name, markers=m, fields=[fiber, sheet, sheet_normal])
Пример #9
0
def gmsh2dolfin(msh_file):

    msh = meshio.gmsh.read(msh_file)

    vertex_mesh = create_mesh(msh, "vertex")
    line_mesh = create_mesh(msh, "line")
    triangle_mesh = create_mesh(msh, "triangle")
    tetra_mesh = create_mesh(msh, "tetra")

    vertex_mesh_name = Path("vertex_mesh.xdmf")
    meshio.write(vertex_mesh_name, vertex_mesh)

    line_mesh_name = Path("line_mesh.xdmf")
    meshio.write(line_mesh_name, line_mesh)

    triangle_mesh_name = Path("triangle_mesh.xdmf")
    meshio.write(triangle_mesh_name, triangle_mesh)

    tetra_mesh_name = Path("mesh.xdmf")
    meshio.write(
        tetra_mesh_name,
        tetra_mesh,
    )

    mesh = dolfin.Mesh()

    with dolfin.XDMFFile(tetra_mesh_name.as_posix()) as infile:
        infile.read(mesh)

    cfun = dolfin.MeshFunction("size_t", mesh, 3)
    read_meshfunction(tetra_mesh_name, cfun)
    tetra_mesh_name.unlink()
    tetra_mesh_name.with_suffix(".h5").unlink()

    ffun_val = dolfin.MeshValueCollection("size_t", mesh, 2)
    read_meshfunction(triangle_mesh_name, ffun_val)
    ffun = dolfin.MeshFunction("size_t", mesh, ffun_val)
    ffun.array()[ffun.array() == max(ffun.array())] = 0
    triangle_mesh_name.unlink()
    triangle_mesh_name.with_suffix(".h5").unlink()

    efun_val = dolfin.MeshValueCollection("size_t", mesh, 1)
    read_meshfunction(line_mesh_name, efun_val)
    efun = dolfin.MeshFunction("size_t", mesh, efun_val)
    efun.array()[efun.array() == max(efun.array())] = 0
    line_mesh_name.unlink()
    line_mesh_name.with_suffix(".h5").unlink()

    vfun_val = dolfin.MeshValueCollection("size_t", mesh, 0)
    read_meshfunction(vertex_mesh_name, vfun_val)
    vfun = dolfin.MeshFunction("size_t", mesh, vfun_val)
    vfun.array()[vfun.array() == max(vfun.array())] = 0
    vertex_mesh_name.unlink()
    vertex_mesh_name.with_suffix(".h5").unlink()

    markers = msh.field_data

    ldrb_markers = {
        "base": markers["BASE"][0],
        "epi": markers["EPI"][0],
        "lv": markers["ENDO"][0],
    }

    fiber_sheet_system = ldrb.dolfin_ldrb(mesh, "CG_1", ffun, ldrb_markers)

    marker_functions = pulse.MarkerFunctions(vfun=vfun,
                                             efun=efun,
                                             ffun=ffun,
                                             cfun=cfun)
    microstructure = pulse.Microstructure(
        f0=fiber_sheet_system.fiber,
        s0=fiber_sheet_system.sheet,
        n0=fiber_sheet_system.sheet_normal,
    )
    geo = pulse.HeartGeometry(
        mesh=mesh,
        markers=markers,
        marker_functions=marker_functions,
        microstructure=microstructure,
    )
    return geo
Пример #10
0
              beta_endo_sept=0,   # Sheet angle on the Septum endocardium
              beta_epi_sept=0,   # Sheet angle on the Septum epicardium
              alpha_endo_rv=80,    # Fiber angle on the RV endocardium
              alpha_epi_rv=-80,    # Fiber angle on the RV epicardium
              beta_endo_rv=0,      # Sheet angle on the RV endocardium
              beta_epi_rv=0)        # Sheet angle on the RV epicardium

# Choose space for the fiber fields.
# This is a string on the form {family}_{degree}
fiber_space = 'Quadrature_2'
# fiber_space = 'Lagrange_1'

# Compute the microstructure
fiber, sheet, sheet_normal = ldrb.dolfin_ldrb(mesh=mesh,
                                              fiber_space=fiber_space,
                                              ffun=ffun,
                                              markers=markers,
                                              log_level=df.debug,
                                              **angles)

# # Store the results
df.File('biv_fiber.xml') << fiber
df.File('biv_sheet.xml') << sheet
df.File('biv_sheet_normal.xml') << sheet_normal

# If you run in paralell you should skip the visualization step and do that in
# serial in stead. In that case you can read the the functions from the xml
# Using the following code
# V = ldrb.space_from_string(fiber_space, mesh, dim=3)
# fiber = df.Function(V, 'biv_fiber.xml')
# sheet = df.Function(V, 'biv_sheet.xml')
# sheet_normal = df.Function(V, 'biv_sheet_normal.xml')
Пример #11
0
ldrb_markers = {
    "epi": markers["Epicardium"][0],
    "lv": markers["Endocardium"][0],
    "base": markers["Basal plane"][0],
}

# Select linear langange elements

fiber_space = "P_1"

# Compute the fiber-sheet system

fiber, sheet, sheet_normal = ldrb.dolfin_ldrb(
    mesh=mesh,
    fiber_space=fiber_space,
    ffun=ffun,
    markers=ldrb_markers,
    alpha_endo_lv=60,  # Fiber angle on the endocardium
    alpha_epi_lv=-60,  # Fiber angle on the epicardium
    beta_endo_lv=0,  # Sheet angle on the endocardium
    beta_epi_lv=0,  # Sheet angle on the epicardium
)

# And save the results

with dolfin.XDMFFile(mesh.mpi_comm(), "idealized_LV_fiber.xdmf") as xdmf:
    xdmf.write(fiber)

# ![_](_static/figures/idealized_LV_fiber.png)
Пример #12
0
    xdmf.read(ffun)

# Choose space for the fiber fields
# This is a string on the form {family}_{degree}
fiber_space = "Lagrange_2"

# Compute the microstructure
fiber, sheet, sheet_normal = ldrb.dolfin_ldrb(
    mesh=mesh,
    fiber_space=fiber_space,
    ffun=ffun,
    markers=markers,
    alpha_endo_lv=30,  # Fiber angle on the LV endocardium
    alpha_epi_lv=-30,  # Fiber angle on the LV epicardium
    beta_endo_lv=0,  # Sheet angle on the LV endocardium
    beta_epi_lv=0,  # Sheet angle on the LV epicardium
    alpha_endo_sept=60,  # Fiber angle on the Septum endocardium
    alpha_epi_sept=-60,  # Fiber angle on the Septum epicardium
    beta_endo_sept=0,  # Sheet angle on the Septum endocardium
    beta_epi_sept=0,  # Sheet angle on the Septum epicardium
    alpha_endo_rv=80,  # Fiber angle on the RV endocardium
    alpha_epi_rv=-80,  # Fiber angle on the RV epicardium
    beta_endo_rv=0,  # Sheet angle on the RV endocardium
    beta_epi_rv=0,
)

# Store the results
with df.HDF5File(mesh.mpi_comm(), "biv.h5", "w") as h5file:
    h5file.write(fiber, "/fiber")
    h5file.write(sheet, "/sheet")
    h5file.write(sheet_normal, "/sheet_normal")
Пример #13
0
def test_markers(lv_mesh):

    markers = dict(base=10, lv=30, epi=40)
    system = ldrb.dolfin_ldrb(lv_mesh, 'Lagrange_1', markers=markers)
Пример #14
0
def test_lv_regression(lv_mesh, fiber_space):
    system = ldrb.dolfin_ldrb(lv_mesh, fiber_space)