Exemplo n.º 1
0
    def __init__(
        self,
        activation=None,
        f0=None,
        s0=None,
        n0=None,
        model: ActiveModels = ActiveModels.active_strain,
        active_isotropy: ActiveStressModels = ActiveStressModels.transversally,
        eta: Optional[float] = None,
        T_ref: Optional[float] = None,
        isochoric=True,
    ):
        # Fiber system
        self.f0 = f0
        self.s0 = s0
        self.n0 = n0

        self._activation = (Constant(0, name="activation")
                            if activation is None else activation)

        self.T_ref = (Constant(T_ref, name="T_ref")
                      if T_ref else Constant(1.0, name="T_ref"))

        self.eta = Constant(eta, name="eta") if eta else Constant(0.0,
                                                                  name="eta")
        self.isochoric = isochoric
        self.active_isotropy = active_isotropy
        self.model = model
Exemplo n.º 2
0
    def __init__(
        self,
        activation=None,
        f0=None,
        s0=None,
        n0=None,
        T_ref=None,
        isochoric=True,
        *args,
        **kwargs
    ):

        # Fiber system
        self.f0 = f0
        self.s0 = s0
        self.n0 = n0

        self._activation = (
            Constant(0, name="activation") if activation is None else activation
        )

        self.T_ref = (
            Constant(T_ref, name="T_ref") if T_ref else Constant(1.0, name="T_ref")
        )

        kinematics.Invariants.__init__(self, isochoric, *args)
def dirichlet_bc(W):
    V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
    return [
        DirichletBC(V.sub(0), Constant(-x_strain), xlow),
        DirichletBC(V.sub(0), Constant(x_strain), xhigh),
        DirichletBC(V.sub(1), Constant(-y_strain), ylow),
        DirichletBC(V.sub(1), Constant(y_strain), yhigh),
    ]
Exemplo n.º 4
0
    def strain_energy(self, F_):
        """
        UFL form of the strain energy.
        """

        params = self.parameters

        # Elastic part of deformation gradient
        F = self.Fe(F_)

        E = kinematics.GreenLagrangeStrain(F, isochoric=self.isochoric)

        CC = Constant(params["C"], name="C")

        e1 = self.f0
        e2 = self.s0
        e3 = self.n0

        if any(e is None for e in (e1, e2, e3)):
            msg = ("Need to provide the full orthotropic basis "
                   "for the Guccione model got \ne1 = {e1}\n"
                   "e2 = {e2}\ne3 = {e3}").format(e1=e1, e2=e2, e3=e3)
            raise ValueError(msg)

        if self.is_isotropic():
            # isotropic case
            Q = dolfin.inner(E, E)

        else:
            # fully anisotropic
            bt = Constant(params["bt"], name="bt")
            bf = Constant(params["bf"], name="bf")
            bfs = Constant(params["bfs"], name="bfs")

            E11, E12, E13 = (
                dolfin.inner(E * e1, e1),
                dolfin.inner(E * e1, e2),
                dolfin.inner(E * e1, e3),
            )
            _, E22, E23 = (
                dolfin.inner(E * e2, e1),
                dolfin.inner(E * e2, e2),
                dolfin.inner(E * e2, e3),
            )
            _, _, E33 = (
                dolfin.inner(E * e3, e1),
                dolfin.inner(E * e3, e2),
                dolfin.inner(E * e3, e3),
            )

            Q = (bf * E11**2 + bt * (E22**2 + E33**2 + 2 * E23**2) + bfs *
                 (2 * E12**2 + 2 * E13**2))

        # passive strain energy
        Wpassive = CC / 2.0 * (dolfin.exp(Q) - 1)
        Wactive = self.Wactive(F, diff=0)

        return Wpassive + Wactive
Exemplo n.º 5
0
def dirichlet_bc(W):
    V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
    return [
        DirichletBC(V.sub(0), Constant(-x_strain), xlow),
        DirichletBC(V.sub(0), Constant(x_strain), xhigh),
        DirichletBC(V.sub(1), Constant(-y_strain), ylow),
        DirichletBC(V.sub(1), Constant(y_strain), yhigh),
        DirichletBC(V, np.zeros(3), center, method="pointwise"),
    ]
Exemplo n.º 6
0
    def __init__(self, w=None, eta=None, dim=None):
        self.w = Constant(w, name="width")
        self.eta = Constant(eta, name="eta")

        W, eta, x1, x2 = sp.symbols('w, eta, x[0], x[1]')
        self.dependencies = [W, eta]
        X, Z = ligaro(W, eta)
        #        R = L/eta

        if dim == 2:
            self.gamma_sp = gamma_sp = [X, Z]
            self.Gsub2 = None
        if dim == 3:
            self.gamma_sp = gamma_sp = [X, x2, Z]

        # for dim==2 or dim ==3:
        self.gamma = Expression(tuple([ccode(i) for i in gamma_sp]),
                                eta=self.eta,
                                w=self.w,
                                degree=DEGREE,
                                name="gamma")

        self.Gsub1 = self.build_derivative([x1], name='Gsub1')

        if ADJOINT:
            # adjoint gamma
            self.gamma.dependencies = [self.w, self.eta]
            self.gamma.user_defined_derivatives = {}
            self.gamma.user_defined_derivatives[
                self.w] = self.build_derivative([W], name='d_gamma_dw')
            self.gamma.user_defined_derivatives[
                self.eta] = self.build_derivative([eta], name='d_gamma_deta')
            # adjoint Gsub1
            self.Gsub1.dependencies = [self.w, self.eta]
            self.Gsub1.user_defined_derivatives = {}
            self.Gsub1.user_defined_derivatives[
                self.w] = self.build_derivative([x1, W], name='d_Gsub1_dw')
            self.Gsub1.user_defined_derivatives[
                self.eta] = self.build_derivative([x1, eta],
                                                  name='d_Gsub1_deta')

        if dim == 3:
            self.Gsub2 = self.build_derivative([x2], name='Gsub2')

            if ADJOINT:
                self.Gsub2.dependencies = [self.w, self.eta]
                self.Gsub2.user_defined_derivatives = {}
                self.Gsub2.user_defined_derivatives[
                    self.w] = self.build_derivative([x2, W], name='d_Gsub2_dw')
                self.Gsub2.user_defined_derivatives[
                    self.eta] = self.build_derivative([x2, eta],
                                                      name='d_Gsub2_deta')
Exemplo n.º 7
0
def I5(F, a0, isochoric=False):
    if a0 is not None:
        C = RightCauchyGreen(F, isochoric)
        I5 = inner(C * a0, C * a0)
    else:
        I5 = Constant(0.0)
    return I5
    def _set_parameter_attrs(self, geometry=None):
        for k, v in self.parameters.items():

            if isinstance(v, (float, int)):
                setattr(self, k, Constant(v, name=k))

            elif isinstance(v, RegionalParameter):

                if geometry is not None:

                    v_new = RegionalParameter(geometry.sfun)
                    numpy_mpi.assign_to_vector(
                        v_new.vector(),
                        numpy_mpi.gather_vector(v.vector()),
                    )
                    v = v_new

                ind_space = v.proj_space
                setattr(self, k, Function(ind_space, name=k))
                mat = getattr(self, k)
                matfun = v.function
                mat.assign(project(matfun, ind_space))

            else:

                if geometry is not None and v.ufl_element().cell() is not None:
                    v_new = update_function(geometry.mesh, v)
                    v = v_new

                setattr(self, k, v)
Exemplo n.º 9
0
def copy(f, deepcopy=True, name="copied_function"):
    """
    Copy a function. This is to ease the integration
    with dolfin adjoint where copied fuctions are annotated.
    """

    if isinstance(f, (dolfin.Function, Function)):
        if has_dolfin_adjoint:
            try:
                return f.copy(deepcopy=deepcopy, name=name)
            except TypeError:
                return f.copy(deepcopy=deepcopy)
        else:
            return f.copy(deepcopy=deepcopy)
    elif isinstance(f, dolfin.Constant):
        return dolfin.Constant(f, name=name)
    elif isinstance(f, Constant):
        return Constant(f, name=name)
    elif isinstance(f, (float, int)):
        return f
    elif isinstance(f, Enlisted):
        lst = []
        for fi in f:
            lst.append(copy(fi))
        return enlist(lst)

    elif isinstance(f, (list, tuple)):
        lst = []
        for fi in f:
            lst.append(copy(fi))
        return tuple(lst)
    else:
        return f
Exemplo n.º 10
0
def Wactive_orthotropic(Ta, C, f0, s0, n0):
    """Return active strain energy for an orthotropic
    active stress


    Arguments
    ---------
    Ta : dolfin.Function or dolfin.Constant
        A vector function representng the mangnitude of the
        active stress in the reference configuration (firt Pioala).
        Ta = (Ta_f0, Ta_s0, Ta_n0)
    C : ufl.Form
        The right Cauchy-Green deformation tensor
    f0 : dolfin.Function
        A vector function representng the direction of the
        first component
    s0 : dolfin.Function
        A vector function representng the direction of the
        second component
    n0 : dolfin.Function
        A vector function representng the direction of the
        third component
    """
    I4f = dolfin.inner(C * f0, f0)
    I4s = dolfin.inner(C * s0, s0)
    I4n = dolfin.inner(C * n0, n0)

    I4 = dolfin.as_vector([I4f - 1, I4s - 1, I4n - 1])
    return Constant(0.5) * dolfin.inner(Ta, I4)
Exemplo n.º 11
0
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)),
        geometry.ffun,
        geometry.markers["BASE"][0],
    )
Exemplo n.º 12
0
def I4(F, a0=None, isochoric=False):

    if a0 is not None:
        C = RightCauchyGreen(F, isochoric)
        I4 = inner(C * a0, a0)
    else:
        I4 = Constant(0.0)
    return I4
Exemplo n.º 13
0
 def assign_control(self, new_control):
     """
     Assign a new value to the control
     """
     for c, n in zip(self.control, new_control):
         try:
             c.assign(n)
         except TypeError:
             c.assign(Constant(n))
Exemplo n.º 14
0
def fix_basal_plane(W):
    V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
    bc = DirichletBC(
        V.sub(0),
        Constant(0.0),
        geometry.ffun,
        geometry.markers["BASE"][0],
    )
    return bc
Exemplo n.º 15
0
    def increment_control(self):

        for c, s in zip(self.control, self.step):
            if isinstance(c, (dolfin.Function, Function)):
                c_arr = numpy_mpi.gather_vector(c.vector())
                c_tmp = Function(c.function_space())
                c_tmp.vector()[:] = c_arr + s
                c.assign(c_tmp)
            else:
                c_arr = c
                c.assign(Constant(constant2float(c) + s))
Exemplo n.º 16
0
    def _init_spaces(self):

        mesh = self.geometry.mesh

        element = dolfin.VectorElement("P", mesh.ufl_cell(), 1)
        self.state_space = dolfin.FunctionSpace(mesh, element)
        self.state = Function(self.state_space)
        self.state_test = dolfin.TestFunction(self.state_space)

        # Add penalty factor
        self.kappa = Constant(1e3)
Exemplo n.º 17
0
    def increment_control(self):

        for c, s in zip(self.control, self.step):
            # if isinstance(s, (dolfin.Function, Function))
            if isinstance(c, (dolfin.Function, Function)):
                c_arr = numpy_mpi.gather_vector(c.vector(), c.function_space().dim())
                c_tmp = Function(c.function_space())
                c_tmp.vector().set_local(np.array(c_arr + s))
                c_tmp.vector().apply("")
                c.assign(c_tmp)
            else:
                c_arr = c
                c.assign(Constant(constant2float(c) + s))
Exemplo n.º 18
0
def get_cavity_volume_form(mesh, u=None, xshift=0.0):

    from . import kinematics

    shift = Constant((xshift, 0.0, 0.0))
    X = dolfin.SpatialCoordinate(mesh) - shift
    N = dolfin.FacetNormal(mesh)

    if u is None:
        vol_form = (-1.0 / 3.0) * dolfin.dot(X, N)
    else:
        F = kinematics.DeformationGradient(u)
        J = kinematics.Jacobian(F)
        vol_form = (-1.0 / 3.0) * dolfin.dot(X + u, J * dolfin.inv(F).T * N)

    return vol_form
Exemplo n.º 19
0
def rigid_motion_term(mesh, u, r):
    position = dolfin.SpatialCoordinate(mesh)
    RM = [
        Constant((1, 0, 0)),
        Constant((0, 1, 0)),
        Constant((0, 0, 1)),
        dolfin.cross(position, Constant((1, 0, 0))),
        dolfin.cross(position, Constant((0, 1, 0))),
        dolfin.cross(position, Constant((0, 0, 1))),
    ]

    return sum(dolfin.dot(u, zi) * r[i] * dolfin.dx for i, zi in enumerate(RM))
Exemplo n.º 20
0
class DummyProblemParameters(FrozenClass):
    """ A set of parameters for a :class:`DummyProblem`.
    """

    domain = None
    dt = None
    rho = 1000.

    # Finite element settings
    finite_element = staticmethod(finite_elements.p2p1)

    # Initial condition
    initial_condition = Constant((1e-16, 0, 0))

    # Tidal farm
    tidal_farm = None

    functional_final_time_only = False
Exemplo n.º 21
0
def test_pass_active_model_as_object(unitcube_geometry):

    activation = Constant(0.001)

    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)

    bcs = BoundaryConditions(dirichlet=(dirichlet_bc,))

    matparams = NeoHookean.default_parameters()

    material = NeoHookean(
        parameters=matparams,
        active_model="active_strain",
        activation=activation,
    )

    problem = MechanicsProblem(unitcube_geometry, material, bcs)
    problem.solve()
    u, p = problem.state.split(deepcopy=True)
    assert np.linalg.norm(u.vector().get_local()) > 0
Exemplo n.º 22
0
def test_active_contraction_yield_displacement(unitcube_geometry, active_model):

    activation = Constant(0.001)

    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)

    bcs = BoundaryConditions(dirichlet=(dirichlet_bc,))

    matparams = HolzapfelOgden.default_parameters()

    material = HolzapfelOgden(
        activation=activation,
        parameters=matparams,
        active_model=active_model,
    )

    problem = MechanicsProblem(unitcube_geometry, material, bcs)
    problem.solve()
    u, p = problem.state.split(deepcopy=True)
    assert np.linalg.norm(u.vector().get_local()) > 0
Exemplo n.º 23
0
def Wactive_transversally(Ta, C, f0, eta=0.0):
    """
    Return active strain energy when activation is only
    working along the fibers, with a possible transverse
    component defined by eta

    Arguments
    ---------
    Ta : dolfin.Function or dolfin.Constant
        A scalar function representng the mangnitude of the
        active stress in the reference configuration (firt Pioala)
    C : ufl.Form
        The right Cauchy-Green deformation tensor
    f0 : dolfin.Function
        A vector function representng the direction of the
        active stress
    eta : float
        Amount of active stress in the transverse direction
        (relative to f0)
    """

    I4f = dolfin.inner(C * f0, f0)
    I1 = dolfin.tr(C)
    return Constant(0.5) * Ta * ((I4f - 1) + eta * ((I1 - 3) - (I4f - 1)))
Exemplo n.º 24
0
)
fiber_space = dolfin.FunctionSpace(mesh, fiber_element)
fiber = Function(fiber_space, "data/fiber.xml")

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
Exemplo n.º 25
0
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)
Exemplo n.º 26
0
# Create the geometry
geometry = pulse.Geometry(
    mesh=mesh,
    marker_functions=marker_functions,
    microstructure=microstructure,
)

# 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)

Exemplo n.º 27
0
    def __init__(self, w=None, eta=None, dim=None, length=1):
        self.w = Constant(w, name="width")
        self.eta = Constant(eta, name="eta")
        self.t = Constant(length, name="length")

        W, eta, x1, x2, t = sp.symbols('w, eta, x[0], x[1], t')
        X, Z = ligaro(W, eta)

        if dim == 2:
            self.Gsub2 = None
            self.gamma_sp = gamma_sp = [X, Z]
            self.gamma = Expression(tuple([ccode(i) for i in gamma_sp]),
                                    eta=self.eta,
                                    w=self.w,
                                    degree=DEGREE,
                                    name="gamma")

        if dim == 3:
            self.gamma_sp = gamma_sp = [X, t * x2, Z]
            # fixed-end open surface volume correction
            # ONLY VALID FOR FIXED EDGES
            R = self.w / sqrt(2 * (1 - cos(self.eta)))
            Area = -0.5 * R**2 * (self.eta - sin(self.eta)
                                  )  # negative because upsidedown #TODO fix
            self.vol_correct = (Area * self.t / 3)

            self.gamma = Expression(tuple([ccode(i) for i in gamma_sp]),
                                    eta=self.eta,
                                    w=self.w,
                                    t=self.t,
                                    degree=DEGREE,
                                    name="gamma")

        self.Gsub1 = self.build_derivative([x1], name='Gsub1')
        if dim == 3:
            self.Gsub2 = self.build_derivative([x2], name='Gsub2')

        if ADJOINT:
            # adjoint gamma
            self.gamma.dependencies = [self.w, self.eta, self.t]
            self.gamma.user_defined_derivatives = {}
            self.gamma.user_defined_derivatives[
                self.w] = self.build_derivative([W], name='d_gamma_dw')
            self.gamma.user_defined_derivatives[
                self.eta] = self.build_derivative([eta], name='d_gamma_deta')
            self.gamma.user_defined_derivatives[
                self.t] = self.build_derivative([t], name='d_gamma_dt')

            # adjoint Gsub1
            self.Gsub1.dependencies = [self.w, self.eta, self.t]
            self.Gsub1.user_defined_derivatives = {}
            self.Gsub1.user_defined_derivatives[
                self.w] = self.build_derivative([x1, W], name='d_Gsub1_dw')
            self.Gsub1.user_defined_derivatives[
                self.eta] = self.build_derivative([x1, eta],
                                                  name='d_Gsub1_deta')
            self.Gsub1.user_defined_derivatives[
                self.t] = self.build_derivative([x1, t], name='d_Gsub1_dt')

            if dim == 3:
                # adjoint Gsub2
                self.Gsub2.dependencies = [self.w, self.eta, self.t]
                self.Gsub2.user_defined_derivatives = {}
                self.Gsub2.user_defined_derivatives[
                    self.w] = self.build_derivative([x2, W], name='d_Gsub2_dw')
                self.Gsub2.user_defined_derivatives[
                    self.eta] = self.build_derivative([x2, eta],
                                                      name='d_Gsub2_deta')
                self.Gsub2.user_defined_derivatives[
                    self.t] = self.build_derivative([x2, t], name='d_Gsub2_dt')
Exemplo n.º 28
0
def test_material(unitcube_geometry, Material, active_model, isochoric):

    compressible_model = "incompressible"

    if active_model == "active_stress":
        active_value = 20.0
        activation = Constant(1.0)
        T_ref = active_value

        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)

    else:
        activation = Constant(0.0)
        active_value = 0.0
        T_ref = 1.0

        def dirichlet_bc(W):
            V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
            return DirichletBC(V.sub(0), Constant(0.0), fixed, "pointwise")

    neumann_bc = NeumannBC(traction=Constant(-active_value), marker=free_marker)

    bcs = BoundaryConditions(dirichlet=(dirichlet_bc,), neumann=(neumann_bc,))

    matparams = Material.default_parameters()

    material = Material(
        activation=activation,
        parameters=matparams,
        T_ref=T_ref,
        isochoric=isochoric,
        compressible_model=compressible_model,
        active_model=active_model,
    )

    assert material.isochoric == isochoric

    problem = MechanicsProblem(unitcube_geometry, material, bcs)
    problem.solve()

    u, p = problem.state.split(deepcopy=True)

    print(material.name)
    if active_model == "active_strain":

        tol = 1e-4

        if not isochoric:
            if material.name in [
                "guccione",
                "linear_elastic",
                "saint_venant_kirchhoff",
            ]:
                assert all(abs(p.vector().get_local()) < tol)
            elif material.name == "holzapfel_ogden":

                assert all(abs(p.vector().get_local() - material.parameters["a"]) < tol)
            elif material.name == "neo_hookean":
                assert all(
                    abs(p.vector().get_local() - material.parameters["mu"]) < tol,
                )
            else:
                raise TypeError(f"Unkown material {material.name}")

        else:
            assert all(abs(p.vector().get_local()) < tol)

    else:

        F = kinematics.DeformationGradient(u)
        T = material.CauchyStress(F, p)

        V_dg = dolfin.FunctionSpace(unitcube_geometry.mesh, "DG", 1)

        # Fiber on current geometry
        f = F * unitcube_geometry.f0

        # Fiber stress
        Tf = dolfin.inner(T * f / f ** 2, f)
        Tf_dg = project(Tf, V_dg)

        tol = 1e-10

        assert all(abs(Tf_dg.vector().get_local() - active_value) < tol)
        assert all(abs(u.vector().get_local()) < tol)

        if not isochoric:
            if material.name in [
                "guccione",
                "linear_elastic",
                "saint_venant_kirchhoff",
            ]:
                assert all(abs(p.vector().get_local()) < tol)
            elif material.name == "holzapfel_ogden":

                assert all(abs(p.vector().get_local() - material.parameters["a"]) < tol)
            elif material.name == "neo_hookean":
                assert all(
                    abs(p.vector().get_local() - material.parameters["mu"]) < tol,
                )
            else:
                raise TypeError(f"Unkown material {material.name}")

        else:

            assert all(abs(p.vector().get_local()) < tol)
Exemplo n.º 29
0
 def dirichlet_bc(W):
     V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
     return DirichletBC(V.sub(0), Constant(0.0), fixed, "pointwise")
Exemplo n.º 30
0
def compute_meshvolume(domain=None, dx=dolfin.dx, subdomain_id=None):
    return Constant(
        assemble(
            Constant(1.0) * dx(domain=domain, subdomain_id=subdomain_id), ), )