Exemple #1
0
def create_forward_problem(
    mesh,
    activation,
    active_value=0.0,
    active_model="active_stain",
    T_ref=1.0,
):

    ffun = df.MeshFunction("size_t", mesh, 2)
    ffun.set_all(0)

    left = df.CompiledSubDomain("on_boundary && near(x[0], 0)")
    left_marker = 1
    left.mark(ffun, left_marker)

    # Collect the functions containing the markers
    marker_functions = pulse.MarkerFunctions(ffun=ffun)

    def dirichlet_bc(W):
        V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
        return da.DirichletBC(V, da.Constant((0.0, 0.0, 0.0)), left)

    bcs = pulse.BoundaryConditions(dirichlet=(dirichlet_bc, ), )

    f0 = df.as_vector([1, 0, 0])
    microstructure = pulse.Microstructure(f0=f0)

    geometry = pulse.Geometry(
        mesh=mesh,
        marker_functions=marker_functions,
        microstructure=microstructure,
    )

    material_parameters = dict(
        a=2.28,
        a_f=1.686,
        b=9.726,
        b_f=15.779,
        a_s=0.0,
        b_s=0.0,
        a_fs=0.0,
        b_fs=0.0,
    )
    material = pulse.HolzapfelOgden(
        active_model=active_model,
        parameters=material_parameters,
        activation=activation,
        T_ref=T_ref,
    )

    problem = pulse.MechanicsProblem(geometry, material, bcs)
    problem.solve()

    if active_value > 0.0:
        pulse.iterate.iterate(problem, activation, active_value)

    return problem
Exemple #2
0
def setup_material(material_model):
    """
    Choose parameters based on

    Hadjicharalambous, Myrianthi, et al. "Analysis of passive
    cardiac constitutive laws for parameter estimation using 3D
    tagged MRI." Biomechanics and modeling in mechanobiology 14.4
    (2015): 807-828.

    These parameters did not really match the Klotz curve here.
    Perhaps they did some more tuning?

    """
    if material_model == "guccione":

        matparams = pulse.Guccione.default_parameters()
        matparams["C"] = 0.18  # kPa
        matparams["bf"] = 27.75
        matparams["bt"] = 5.37
        matparams["bfs"] = 2.445
        material = pulse.Guccione(
            parameters=matparams,
            f0=geometry.f0,
            s0=geometry.s0,
            n0=geometry.n0,
        )

    elif material_model == "neo_hookean":

        matparams = pulse.NeoHookean.default_parameters()
        matparams["mu"] = 10.0  # kPa
        material = pulse.NeoHookean(parameters=matparams)

    elif material_model == "holzapfel_ogden":

        matparams = pulse.HolzapfelOgden.default_parameters()

        matparams["a"] = 4.0  # kPa
        matparams["a_f"] = 10.0  # kPa
        matparams["b"] = 5.0
        matparams["b_f"] = 5.0
        material = pulse.HolzapfelOgden(
            parameters=matparams,
            f0=geometry.f0,
            s0=geometry.s0,
            n0=geometry.n0,
        )
    return material
Exemple #3
0
def build_problem(geometry, matparams):
    activation = dolfin.Function(dolfin.FunctionSpace(geometry.mesh, "R", 0))
    material = pulse.HolzapfelOgden(
        activation=activation,
        parameters=matparams,
        f0=geometry.f0,
        s0=geometry.s0,
        n0=geometry.n0,
    )

    # LV Pressure
    lvp = dolfin.Constant(0.0)
    lv_marker = geometry.markers["ENDO"][0]
    lv_pressure = pulse.NeumannBC(traction=lvp, marker=lv_marker, name="lv")
    neumann_bc = [lv_pressure]

    # Add spring term at the base with stiffness 1.0 kPa/cm^2
    base_spring = 1.0
    robin_bc = [
        pulse.RobinBC(
            value=dolfin.Constant(base_spring), marker=geometry.markers["BASE"][0]
        )
    ]

    # 0 in V.sub(0) refers to x-direction, which is the longitudinal direction
    def fix_basal_plane(W):
        V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
        bc = dolfin.DirichletBC(
            V.sub(0), dolfin.Constant(0.0), geometry.ffun, geometry.markers["BASE"][0]
        )
        return bc

    dirichlet_bc = [fix_basal_plane]

    # Collect boundary conditions
    bcs = pulse.BoundaryConditions(
        dirichlet=dirichlet_bc, neumann=neumann_bc, robin=robin_bc
    )

    # Create the problem
    problem = pulse.MechanicsProblem(geometry, material, bcs)
    return problem, activation, lvp
Exemple #4
0
)

# Use the default material parameters
material_parameters = pulse.HolzapfelOgden.default_parameters()

# Select model for active contraction
active_model = pulse.ActiveModels.active_strain
# active_model = "active_stress"

# Set the activation
activation = Constant(0.0)

# Create material
material = pulse.HolzapfelOgden(
    active_model=active_model,
    parameters=material_parameters,
    activation=activation,
)


# Make Dirichlet boundary conditions
def dirichlet_bc(W):
    V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
    return DirichletBC(V, Constant((0.0, 0.0, 0.0)), fixed)


# Make Neumann boundary conditions
neumann_bc = pulse.NeumannBC(traction=Constant(0.0), marker=free_marker)

# Collect Boundary Conditions
bcs = pulse.BoundaryConditions(dirichlet=(dirichlet_bc,), neumann=(neumann_bc,))
Exemple #5
0
"""
This demo demonstrates how to unload a geometry using
the backward displament method which is an iterative
fixed point method.
"""
import matplotlib.pyplot as plt
import dolfin
import pulse

geometry = pulse.HeartGeometry.from_file(pulse.mesh_paths['simple_ellipsoid'])

material = pulse.HolzapfelOgden()
# material = pulse.Guccione()

# Parameter for the cardiac boundary conditions
bcs_parameters = pulse.MechanicsProblem.default_bcs_parameters()
bcs_parameters['base_spring'] = 1.0
bcs_parameters['base_bc'] = 'fix_x'

# Create the problem
# When performing unloading you should pass the
# bcs parameters instead of the bcs directly
problem = pulse.MechanicsProblem(geometry,
                                 material,
                                 bcs_parameters=bcs_parameters)

# Suppose geometry is loaded with a pressure of 1 kPa
# and create the unloader
unloader = pulse.FixedPointUnloader(problem=problem, pressure=1.0)

# Unload the geometry
Exemple #6
0
microstructure = pulse.Microstructure(f0=fiber)

# Create the geometry
geometry = pulse.HeartGeometry(
    mesh=mesh,
    markers=markers,
    marker_functions=marker_functions,
    microstructure=microstructure,
)

activation = Function(dolfin.FunctionSpace(geometry.mesh, "R", 0))
activation.assign(Constant(0.0))
matparams = pulse.HolzapfelOgden.default_parameters()
material = pulse.HolzapfelOgden(
    activation=activation,
    parameters=matparams,
    f0=geometry.f0,
)

# LV Pressure
lvp = Constant(0.0)
lv_marker = markers["ENDO"][0]
lv_pressure = pulse.NeumannBC(traction=lvp, marker=lv_marker, name="lv")
neumann_bc = [lv_pressure]

# Add spring term at the base with stiffness 1.0 kPa/cm^2
base_spring = 1.0
robin_bc = [
    pulse.RobinBC(value=Constant(base_spring), marker=markers["BASE"][0])
]
Exemple #7
0
def create_problem():

    geometry = pulse.HeartGeometry.from_file(
        pulse.mesh_paths["simple_ellipsoid"])

    activation = dolfin_adjoint.Function(dolfin.FunctionSpace(
        geometry.mesh, "R", 0),
                                         name="activation")
    activation.assign(dolfin_adjoint.Constant(0.0))
    matparams = pulse.HolzapfelOgden.default_parameters()

    V = dolfin.FunctionSpace(geometry.mesh, "R", 0)
    control = dolfin_adjoint.Function(V)
    control.assign(dolfin_adjoint.Constant(1.0))
    # control = dolfin_adjoint.Constant(1.0, name="matparam control (a)")
    matparams["a"] = control

    f0 = dolfin_adjoint.Function(geometry.f0.function_space())
    f0.assign(geometry.f0)
    s0 = dolfin_adjoint.Function(geometry.s0.function_space())
    s0.assign(geometry.s0)
    n0 = dolfin_adjoint.Function(geometry.n0.function_space())
    n0.assign(geometry.n0)

    material = pulse.HolzapfelOgden(activation=activation,
                                    parameters=matparams,
                                    f0=f0,
                                    s0=s0,
                                    n0=n0)

    # LV Pressure
    lvp = dolfin_adjoint.Constant(0.0, name="lvp")
    lv_marker = geometry.markers["ENDO"][0]
    lv_pressure = pulse.NeumannBC(traction=lvp, marker=lv_marker, name="lv")
    neumann_bc = [lv_pressure]

    # Add spring term at the base with stiffness 1.0 kPa/cm^2
    base_spring = 1.0
    robin_bc = [
        pulse.RobinBC(
            value=dolfin_adjoint.Constant(base_spring, name="base_spring"),
            marker=geometry.markers["BASE"][0],
        )
    ]

    # Fix the basal plane in the longitudinal direction
    # 0 in V.sub(0) refers to x-direction, which is the longitudinal direction
    def fix_basal_plane(W):
        V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
        bc = dolfin_adjoint.DirichletBC(
            V.sub(0),
            dolfin.Constant(0.0, name="fix_base"),
            geometry.ffun,
            geometry.markers["BASE"][0],
        )
        return bc

    dirichlet_bc = [fix_basal_plane]

    # Collect boundary conditions
    bcs = pulse.BoundaryConditions(dirichlet=dirichlet_bc,
                                   neumann=neumann_bc,
                                   robin=robin_bc)

    # Create the problem
    problem = pulse.MechanicsProblem(geometry, material, bcs)

    return problem, control
Exemple #8
0
# Use the default material parameters from the paper

material_parameters = {
    "a": 0.059,
    "b": 8.023,
    "a_f": 18.472,
    "b_f": 16.026,
    "a_s": 2.481,
    "b_s": 11.120,
    "a_fs": 0.216,
    "b_fs": 11.436,
}

# Create material

material = pulse.HolzapfelOgden(parameters=material_parameters)

# Make a space for controling the amount of shear displacement

X_space = dolfin.VectorFunctionSpace(mesh, "R", 0)
x = Function(X_space)
zero = Constant((0.0, 0.0, 0.0))

# Make a method that will return


def create_experiment(case):  # noqa: C901

    if case == "fs":

        def dirichlet_bc(W):
import pulse
from fenics_plotly import plot

gamma_space = "R_0"
geometry = pulse.Geometry.from_file(pulse.mesh_paths["prolate_ellipsoid"])
# geometry = pulse.geometries.prolate_ellipsoid_geometry(mesh_size_factor=3.0)
geometry.mesh.coordinates()[:] *= 0.1
# breakpoint()
activation = Function(dolfin.FunctionSpace(geometry.mesh, "R", 0))

matparams = pulse.HolzapfelOgden.default_parameters()
material = pulse.HolzapfelOgden(
    active_model=pulse.ActiveModels.active_stress,
    T_ref=1.0,  # Total active stress should be activation * T_ref
    eta=0.2,  # Fraction of transverse stress
    activation=activation,
    parameters=matparams,
    f0=geometry.f0,
    s0=geometry.s0,
    n0=geometry.n0,
)

# LV Pressure
lvp = Constant(0.0)
lv_marker = geometry.markers["ENDO"][0]
lv_pressure = pulse.NeumannBC(traction=lvp, marker=lv_marker, name="lv")
neumann_bc = [lv_pressure]

# Add spring term at the base with stiffness 1.0 kPa/cm^2
base_spring = 1.0
robin_bc = [
    pulse.RobinBC(value=Constant(base_spring),
import matplotlib.pyplot as plt
import dolfin
import pulse
from geometry import Geometry, example_meshes


geo = Geometry.from_file(example_meshes['simple_ellipsoid'])

activation = dolfin.Function(dolfin.FunctionSpace(geo.mesh, "R", 0))
activation.assign(dolfin.Constant(0.2))
matparams = pulse.HolzapfelOgden.default_parameters()
material = pulse.HolzapfelOgden(activation=activation,
                                parameters=matparams,
                                f0=geo.f0,
                                s0=geo.s0,
                                n0=geo.n0)

# LV Pressure
lvp = dolfin.Constant(1.0)
lv_marker = geo.markers['ENDO'][0]
lv_pressure = pulse.NeumannBC(traction=lvp,
                              marker=lv_marker, name='lv')
neumann_bc = [lv_pressure]

# Add spring term at the base with stiffness 1.0 kPa/cm^2
base_spring = 1.0
robin_bc = [pulse.RobinBC(value=dolfin.Constant(base_spring),
                          marker=geo.markers["BASE"][0])]


# Fix the basal plane in the longitudinal direction