Пример #1
0
    def unload(self, save=False):
        """
        Unload the geometry
        """
        if save:
            self.save(self.problem.geometry.mesh, "original_geometry/mesh", "0")

        logger.info("".center(72, "-"))
        logger.info("Start unloading".center(72, "-"))
        logger.info("".center(72, "-"))

        logger.info(
            (
                "\nLV Volume of original geometry = "
                "{:.3f} ml".format(self.problem.geometry.cavity_volume(chamber="lv"))
            ),
        )
        if self.problem.geometry.is_biv:
            logger.info(
                (
                    "RV Volume of original geometry = "
                    "{:.3f} ml".format(
                        self.problem.geometry.cavity_volume(chamber="rv"),
                    )
                ),
            )

        residual = utils.ResidualCalculator(self.problem.geometry.mesh)

        u = self.initial_solve(True)
        self.U = Function(u.function_space())

        self.unload_step(u, residual, save=save)

        logger.info("".center(72, "#") + "\nUnloading suceeding")
Пример #2
0
 def backward_displacement(self):
     """
     Return the current backward displacement as a
     function on the original geometry.
     """
     W = dolfin.VectorFunctionSpace(self.U.function_space().mesh(), "CG", 1)
     u_int = interpolate(self.U, W)
     u = Function(W)
     u.vector()[:] = -1 * u_int.vector()
     return u
Пример #3
0
def update_function(mesh, f):
    """Given a function :math:`f` defined on some domain,
    update the function so that it now is defined on the domain
    given in the mesh
    """

    f_new = Function(dolfin.FunctionSpace(mesh, f.ufl_element()))
    numpy_mpi.assign_to_vector(f_new.vector(),
                               numpy_mpi.gather_vector(f.vector()))
    return f_new
Пример #4
0
    def assign_sub(self, f, i):
        """
        Assign subfunction

        :param f: The function you want to assign
        :param int i: The subspace number

        """
        f_ = Function(self.basespace)
        f_.assign(f)
        self.function_assigner[i].assign(self.split()[i], f_)
Пример #5
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))
Пример #6
0
def calc_cross_products(e1, e2, VV):
    e_crossed = Function(VV)

    e1_arr = e1.vector().get_local().reshape((-1, 3))
    e2_arr = e2.vector().get_local().reshape((-1, 3))

    crosses = []
    for c1, c2 in zip(e1_arr, e2_arr):
        crosses.extend(np.cross(c1, c2.tolist()))

    e_crossed.vector()[:] = np.array(crosses)[:]
    return e_crossed
    def _init_spaces(self):

        logger.debug("Initialize spaces for mechanics problem")
        mesh = self.geometry.mesh

        P2 = dolfin.VectorElement("Lagrange", mesh.ufl_cell(), 2)
        P1 = dolfin.FiniteElement("Lagrange", mesh.ufl_cell(), 1)

        # P2_space = FunctionSpace(mesh, P2)
        # P1_space = FunctionSpace(mesh, P1)
        self.state_space = dolfin.FunctionSpace(mesh, P2 * P1)

        self.state = Function(self.state_space, name="state")
        self.state_test = dolfin.TestFunction(self.state_space)
Пример #8
0
    def __init__(self, fun, n, name="material_parameters"):
        """
        Initialize Mixed parameter.

        This will instanciate a function in a dolfin.MixedFunctionSpace
        consiting of `n` subspaces of the same type as `fun`.
        This is of course easy for the case when `fun` is a normal
        dolfin function, but in the case of a `RegionalParameter` it
        is not that straight forward.
        This class handles this case as well.


        :param fun: The type of you want to make a du
        :type fun: (:py:class:`dolfin.Function`)
        :param int n: number of subspaces
        :param str name: Name of the function

        .. todo::

           Implement support for MixedParameter with different
           types of subspaces, e.g [RegionalParamter, R_0, CG_1]

        """

        msg = "Please provide a dolin function as argument to MixedParameter"
        assert isinstance(fun,
                          (dolfin.Function, Function, RegionalParameter)), msg

        if isinstance(fun, RegionalParameter):
            raise NotImplementedError

        # We can just make a usual mixed function space
        # with n copies of the original one
        V = fun.function_space()
        W = dolfin.MixedFunctionSpace([V] * n)

        Function.__init__(self, W, name=name)

        # Create a function assigner
        self.function_assigner = [
            FunctionAssigner(W.sub(i), V) for i in range(n)
        ]

        # Store the original function space
        self.basespace = V

        if isinstance(fun, RegionalParameter):
            self._meshfunction = fun._meshfunction
Пример #9
0
def make_mechanics_problem(geometry, space="R_0"):

    # Material = NeoHookean
    Material = HolzapfelOgden

    if space == 'regional':
        activation = RegionalParameter(geometry.cfun)
    else:
        family, degree = space.split('_')
        activation = Function(
            dolfin.FunctionSpace(geometry.mesh, family, int(degree)))

    matparams = Material.default_parameters()
    # mu = RegionalParameter(geometry.cfun)
    # mu_val = get_constant(mu.value_size(), value_rank=0, val=matparams["mu"])
    # mu.assign(mu_val)
    # matparams["mu"] = mu

    material = Material(activation=activation,
                        parameters=matparams,
                        f0=geometry.f0,
                        s0=geometry.s0,
                        n0=geometry.n0)

    #bcs = cardiac_boundary_conditions(geometry, base_spring=1.0)
    bcs_parameters = MechanicsProblem.default_bcs_parameters()
    bcs_parameters['base_spring'] = 1.0
    bcs_parameters['base_bc'] = 'fix_x'

    problem = MechanicsProblem(geometry,
                               material,
                               bcs_parameters=bcs_parameters)

    return problem
Пример #10
0
def load_local_basis(h5file, lgroup, mesh, geo):

    if h5file.has_dataset(lgroup):
        # Get local bais functions
        local_basis_attrs = h5file.attributes(lgroup)
        lspace = local_basis_attrs["space"]
        family, order = lspace.split("_")

        namesstr = local_basis_attrs["names"]
        names = namesstr.split(":")

        if DOLFIN_VERSION_MAJOR > 1.6:
            elm = dolfin.VectorElement(
                family=family,
                cell=mesh.ufl_cell(),
                degree=int(order),
                quad_scheme="default",
            )
            V = dolfin.FunctionSpace(mesh, elm)
        else:
            V = dolfin.VectorFunctionSpace(mesh, family, int(order))

        for name in names:
            lb = Function(V, name=name)

            io_utils.read_h5file(h5file, lb, lgroup + "/{}".format(name))
            setattr(geo, name, lb)
    else:
        setattr(geo, "circumferential", None)
        setattr(geo, "radial", None)
        setattr(geo, "longitudinal", None)
    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)
Пример #12
0
def map_vector_field(f0, new_mesh, u=None, name="fiber", normalize=True):
    """
    Map a vector field (f0) onto a new mesh (new_mesh) where the new mesh
    can be a moved version of the original one according to some
    displacement (u). In that case we will just a Piola transform to
    map the vector field.
    """
    representation = dolfin.parameters["form_compiler"]["representation"]
    if DOLFIN_VERSION_MAJOR > 2016:
        dolfin.parameters["form_compiler"]["representation"] = "quadrature"

    dolfin.parameters["form_compiler"]["quadrature_degree"] = 4

    ufl_elem = f0.function_space().ufl_element()
    f0_new = Function(dolfin.FunctionSpace(new_mesh, ufl_elem))

    if u is not None:

        f0_mesh = f0.function_space().mesh()
        u_elm = u.function_space().ufl_element()
        V = dolfin.FunctionSpace(f0_mesh, u_elm)
        u0 = Function(V)
        # arr = numpy_mpi.gather_vector(u.vector())
        # numpy_mpi.assign_to_vector(u0.vector(), arr)
        u0.vector()[:] = u.vector()
        from .kinematics import DeformationGradient

        F = DeformationGradient(u0)

        f0_updated = project(F * f0, f0.function_space())

        if normalize:
            f0_updated = normalize_vector_field(f0_updated)

        f0_new.vector()[:] = f0_updated.vector()
        # f0_arr = numpy_mpi.gather_vector(f0_updated.vector())
        # numpy_mpi.assign_to_vector(f0_new.vector(), f0_arr)

    else:
        # f0_arr = numpy_mpi.gather_vector(f0.vector())
        # numpy_mpi.assign_to_vector(f0_new.vector(), f0_arr)
        f0_new.vector()[:] = f0.vector()

    if DOLFIN_VERSION_MAJOR > 2016:
        dolfin.parameters["form_compiler"]["representation"] = representation

    return f0_new
Пример #13
0
def get_initial_step(current, target, nsteps=5):
    """
    Estimate the step size needed to step from current to target
    in `nsteps`.
    """

    diff = get_diff(current, target)
    if isinstance(diff, dolfin.GenericVector):
        step = Function(current.function_space())
        step.vector().axpy(1.0 / float(nsteps), diff)

    else:
        step = diff / float(nsteps)

    logger.debug(("Intial number of steps: {} with step size {}"
                  "").format(nsteps, step), )
    return step
Пример #14
0
def vectorfield_to_components(u, S, dim):
    components = [Function(S) for i in range(dim)]
    assigners = [
        FunctionAssigner(S,
                         u.function_space().sub(i)) for i in range(dim)
    ]
    for i, comp, assigner in zip(range(dim), components, assigners):
        assigner.assign(comp, u.split()[i])

    return components
Пример #15
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)
Пример #16
0
    def __init__(
        self,
        problem,
        pressure,
        h5name="test.h5",
        options=None,
        h5group="",
        overwrite=False,
        merge_control="",
    ):

        self.problem = problem
        self.pressure = pressure

        self.U = Function(problem.get_displacement(annotate=True).function_space())

        self.merge_control = merge_control
        self.h5name = h5name
        self.h5group = h5group

        if os.path.isfile(h5name) and overwrite:
            if mpi_comm_world().rank == 0:
                os.remove(h5name)

        self.n = int(np.rint(np.max(np.divide(pressure, 0.4))))

        self.parameters = self.default_parameters()
        if options is not None:
            self.parameters.update(**options)

        msg = (
            "\n\n"
            + " Unloading options ".center(72, "-")
            + "\n\n"
            + f"\tTarget pressure: {pressure}\n"
            + f"\tmaxiter = {self.parameters['maxiter']}\n"
            + f"\ttolerance = {self.parameters['tol']}\n"
            + "\tregenerate_fibers (serial only)= "
            "{}\n\n".format(self.parameters["regen_fibers"]) + "".center(72, "-") + "\n"
        )
        logger.info(msg)
Пример #17
0
    def _init_spaces(self):

        mesh = self.geometry.mesh

        P1 = dolfin.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
        P2 = dolfin.VectorElement("Lagrange", mesh.ufl_cell(), 2)
        P3 = dolfin.VectorElement("Real", mesh.ufl_cell(), 0, 6)

        self.state_space = dolfin.FunctionSpace(mesh, dolfin.MixedElement([P1, P2, P3]))

        self.state = Function(self.state_space, name="state")
        self.state_test = dolfin.TestFunction(self.state_space)
Пример #18
0
    def change_step_for_final_iteration(self, prev_control):
        """Change step size so that target is
        reached in the next iteration
        """
        logger.debug("Change step size for final iteration")

        target = delist(self.target)
        prev_control = delist(prev_control)

        if isinstance(target, (dolfin.Function, Function)):
            step = Function(target.function_space())
            step.vector().axpy(1.0, target.vector())
            step.vector().axpy(-1.0, prev_control.vector())
        elif isinstance(target, (list, np.ndarray, tuple)):
            if isinstance(prev_control, (dolfin.Function, Function)):
                prev = numpy_mpi.gather_vector(
                    prev_control.vector(),
                    prev_control.function_space().dim(),
                )
            else:
                prev = prev_control

            step = np.array([
                constant2float(t) - constant2float(c)
                for (t, c) in zip(target, prev)
            ], )
        elif isinstance(target, (dolfin.Constant, Constant)):
            step = constant2float(target) - constant2float(prev_control)
        else:
            step = target - prev_control

        self.step = step
    def get_displacement(self, annotate=False):

        D = self.state_space.sub(0)
        V = D.collapse()

        fa = FunctionAssigner(V, D)
        u = Function(V, name="displacement")

        if has_dolfin_adjoint:
            fa.assign(u, self.state.split()[0], annotate=annotate)
        else:
            fa.assign(u, self.state.split()[0])

        return u
Пример #20
0
    def __init__(self, meshfunction):

        # assert isinstance(
        #     meshfunction, dolfin.MeshFunctionSizet
        # ), "Invalid meshfunction for regional gamma"

        mesh = meshfunction.mesh()

        # FIXME
        self._values = set(numpy_mpi.gather_broadcast(meshfunction.array()))
        self._nvalues = len(self._values)

        V = dolfin.VectorFunctionSpace(mesh, "R", 0, dim=self._nvalues)

        Function.__init__(self, V)
        self._meshfunction = meshfunction

        # Functionspace for the indicator functions
        self._proj_space = dolfin.FunctionSpace(mesh, "DG", 0)

        # Make indicator functions
        self._ind_functions = []
        for v in self._values:
            self._ind_functions.append(self._make_indicator_function(v))
Пример #21
0
def move(mesh, u, factor=1.0):
    """
    Move mesh according to some displacement times some factor
    """
    W = dolfin.VectorFunctionSpace(u.function_space().mesh(), "CG", 1)

    # Use interpolation for now. It is the only thing that makes sense
    u_int = interpolate(u, W)

    u0 = Function(W)
    # arr = factor * numpy_mpi.gather_vector(u_int.vector())
    # numpy_mpi.assign_to_vector(u0.vector(), arr)
    u0.vector()[:] = factor * u_int.vector()
    V = dolfin.VectorFunctionSpace(mesh, "CG", 1)
    U = Function(V)
    U.vector()[:] = u0.vector()
    # numpy_mpi.assign_to_vector(U.vector(), arr)

    dolfin.ALE.move(mesh, U)

    return u0
Пример #22
0
def load_microstructure(h5file, fgroup, mesh, geo, include_sheets=True):

    if h5file.has_dataset(fgroup):
        # Get fibers
        fiber_attrs = h5file.attributes(fgroup)
        fspace = fiber_attrs["space"]
        if fspace is None:
            # Assume quadrature 4
            # family = "Quadrature"
            # order = 4
            family = "CG"
            order = 1
        else:
            family, order = fspace.split("_")

        namesstr = fiber_attrs["names"]
        if namesstr is None:
            names = ["fiber"]
        else:
            names = namesstr.split(":")

        # Check that these fibers exists
        for name in names:
            fsubgroup = fgroup + f"/{name}"
            if not h5file.has_dataset(fsubgroup):
                msg = ("H5File does not have dataset {}").format(fsubgroup)
                logger.warning(msg)

        if DOLFIN_VERSION_MAJOR > 1.6:
            elm = dolfin.VectorElement(
                family=family,
                cell=mesh.ufl_cell(),
                degree=int(order),
                quad_scheme="default",
            )
            V = dolfin.FunctionSpace(mesh, elm)
        else:
            V = dolfin.VectorFunctionSpace(mesh, family, int(order))

        attrs = ["f0", "s0", "n0"]
        for i, name in enumerate(names):
            func = Function(V, name=name)
            fsubgroup = fgroup + f"/{name}"

            io_utils.read_h5file(h5file, func, fsubgroup)

            setattr(geo, attrs[i], func)
Пример #23
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))
Пример #24
0
def make_unit_vector(V, VV, dofs_x, fill_coordinates, foc=None):
    e_c_x = Function(V)
    e_c_y = Function(V)
    e_c_z = Function(V)

    for i, coord in enumerate(dofs_x):
        fill_coordinates(i, e_c_x, e_c_y, e_c_z, coord, foc)

    e = Function(VV)

    fa = [FunctionAssigner(VV.sub(i), V) for i in range(3)]
    for i, e_c_comp in enumerate([e_c_x, e_c_y, e_c_z]):
        fa[i].assign(e.split()[i], e_c_comp)
    return e
Пример #25
0
f0 = interpolate(Expression(("1.0", "0.0", "0.0"), degree=1), V_f)
# Sheets
s0 = interpolate(Expression(("0.0", "1.0", "0.0"), degree=1), V_f)
# Fiber-sheet normal
n0 = interpolate(Expression(("0.0", "0.0", "1.0"), degree=1), V_f)

microstructure = pulse.Microstructure(f0=f0, s0=s0, n0=n0)

# Create the geometry
geometry = pulse.Geometry(
    mesh=mesh,
    microstructure=microstructure,
)
# -

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

problem = RigidMotionProblem(geometry, material)

problem.solve()

u = problem.state.split(deepcopy=True)[1]
Пример #26
0
    def _make_indicator_function(self, marker):

        dofs = self._meshfunction.where_equal(marker)
        f = Function(self._proj_space)
        f.vector()[dofs] = 1.0
        return f
class MechanicsProblem(object):
    """
    Base class for mechanics problem
    """
    def __init__(
        self,
        geometry: Geometry,
        material: Material,
        bcs=None,
        bcs_parameters=None,
        solver_parameters=None,
    ):

        logger.debug("Initialize mechanics problem")
        self.geometry = geometry
        self.material = material

        self._handle_bcs(bcs=bcs, bcs_parameters=bcs_parameters)

        # Make sure that the material has microstructure information
        for attr in ("f0", "s0", "n0"):
            setattr(self.material, attr, getattr(self.geometry, attr))

        self.solver_parameters = NonlinearSolver.default_solver_parameters()
        if solver_parameters is not None:
            self.solver_parameters.update(**solver_parameters)

        self._init_spaces()
        self._init_forms()

    def _handle_bcs(self, bcs, bcs_parameters):
        if bcs is None:
            if isinstance(self.geometry, HeartGeometry):
                self.bcs_parameters = MechanicsProblem.default_bcs_parameters()
                if bcs_parameters is not None:
                    self.bcs_parameters.update(**bcs_parameters)
            else:
                raise ValueError(("Please provive boundary conditions "
                                  "to MechanicsProblem"), )

            self.bcs = cardiac_boundary_conditions(self.geometry,
                                                   **self.bcs_parameters)

        else:
            self.bcs = bcs

            # TODO: FIX THIS or require this
            # Just store this as well in case both is provided
            self.bcs_parameters = MechanicsProblem.default_bcs_parameters()
            if bcs_parameters is not None:
                self.bcs_parameters.update(**bcs_parameters)

    @staticmethod
    def default_bcs_parameters():
        return dict(pericardium_spring=0.0, base_spring=0.0, base_bc="fixed")

    def _init_spaces(self):

        logger.debug("Initialize spaces for mechanics problem")
        mesh = self.geometry.mesh

        P2 = dolfin.VectorElement("Lagrange", mesh.ufl_cell(), 2)
        P1 = dolfin.FiniteElement("Lagrange", mesh.ufl_cell(), 1)

        # P2_space = FunctionSpace(mesh, P2)
        # P1_space = FunctionSpace(mesh, P1)
        self.state_space = dolfin.FunctionSpace(mesh, P2 * P1)

        self.state = Function(self.state_space, name="state")
        self.state_test = dolfin.TestFunction(self.state_space)

    def _init_forms(self):

        logger.debug("Initialize forms mechanics problem")
        # Displacement and hydrostatic_pressure
        u, p = dolfin.split(self.state)
        v, q = dolfin.split(self.state_test)

        # Some mechanical quantities
        F = dolfin.variable(kinematics.DeformationGradient(u))
        J = kinematics.Jacobian(F)
        dx = self.geometry.dx

        internal_energy = (self.material.strain_energy(F, ) +
                           self.material.compressibility(p, J))

        self._virtual_work = dolfin.derivative(
            internal_energy * dx,
            self.state,
            self.state_test,
        )

        external_work = self._external_work(u, v)
        if external_work is not None:
            self._virtual_work += external_work

        self._set_dirichlet_bc()
        self._jacobian = dolfin.derivative(
            self._virtual_work,
            self.state,
            dolfin.TrialFunction(self.state_space),
        )
        self._init_solver()

    def _init_solver(self):
        if has_dolfin_adjoint:
            self._problem = NonlinearVariationalProblem(
                J=self._jacobian,
                F=self._virtual_work,
                u=self.state,
                bcs=self._dirichlet_bc,
            )
            self.solver = NonlinearVariationalSolver(self._problem)
        else:
            self._problem = NonlinearProblem(
                J=self._jacobian,
                F=self._virtual_work,
                bcs=self._dirichlet_bc,
            )
            self.solver = NonlinearSolver(
                self._problem,
                self.state,
                parameters=self.solver_parameters,
            )

    def _set_dirichlet_bc(self):
        # DirichletBC
        for dirichlet_bc in self.bcs.dirichlet:

            msg = ("DirichletBC only implemented for as "
                   "callable. Please provide DirichletBC "
                   "as a callable with argument being the "
                   "state space only")

            if hasattr(dirichlet_bc, "__call__"):
                try:
                    self._dirichlet_bc = dirichlet_bc(self.state_space)
                except Exception as ex:
                    logger.error(msg)
                    raise ex
            else:

                raise NotImplementedError(msg)

    def _external_work(self, u, v):

        F = dolfin.variable(kinematics.DeformationGradient(u))

        N = self.geometry.facet_normal
        ds = self.geometry.ds
        dx = self.geometry.dx

        external_work = []

        for neumann in self.bcs.neumann:

            n = neumann.traction * ufl.cofac(F) * N
            external_work.append(dolfin.inner(v, n) * ds(neumann.marker))

        for robin in self.bcs.robin:

            external_work.append(
                dolfin.inner(robin.value * u, v) * ds(robin.marker))

        for body_force in self.bcs.body_force:

            external_work.append(
                -dolfin.derivative(dolfin.inner(body_force, u) * dx, u, v), )

        if len(external_work) > 0:
            return list_sum(external_work)

        return None

    def reinit(self, state, annotate=False):
        """Reinitialze state"""

        if has_dolfin_adjoint:
            try:
                self.state.assign(state, annotate=annotate)
            except Exception as ex:
                print(ex)
                self.state.assign(state)
        else:
            self.state.assign(state)

        self._init_forms()

    @staticmethod
    def default_solver_parameters():
        return NonlinearSolver.default_solver_parameters()

    def solve(self):
        r"""
        Solve the variational problem

        .. math::

           \delta W = 0

        """

        logger.debug("Solving variational problem")
        # Get old state in case of non-convergence
        if has_dolfin_adjoint:
            try:
                old_state = self.state.copy(deepcopy=True,
                                            name="Old state (pulse)")
            except TypeError:
                # In case this is a dolfin fuction and not a
                # dolfin-adjoint function
                old_state = self.state.copy(deepcopy=True)

        else:
            old_state = self.state.copy(deepcopy=True)

        try:
            logger.debug("Try to solve")
            nliter, nlconv = self.solver.solve()

            if not nlconv:
                logger.debug("Failed")
                raise SolverDidNotConverge("Solver did not converge...")

        except RuntimeError as ex:
            logger.debug("Failed")
            logger.debug("Reintialize old state and raise exception")

            self.reinit(old_state)

            raise SolverDidNotConverge(ex) from ex
        else:
            logger.debug("Sucess")

        return nliter, nlconv

    def get_displacement(self, annotate=False):

        D = self.state_space.sub(0)
        V = D.collapse()

        fa = FunctionAssigner(V, D)
        u = Function(V, name="displacement")

        if has_dolfin_adjoint:
            fa.assign(u, self.state.split()[0], annotate=annotate)
        else:
            fa.assign(u, self.state.split()[0])

        return u

    def SecondPiolaStress(self):
        u, p = self.state.split(deepcopy=True)
        F = kinematics.DeformationGradient(u)
        return self.material.SecondPiolaStress(F, p)

    def FirstPiolaStress(self):
        u, p = self.state.split(deepcopy=True)
        F = kinematics.DeformationGradient(u)
        return self.material.FirstPiolaStress(F, p)

    def ChachyStress(self):
        u, p = self.state.split(deepcopy=True)
        F = kinematics.DeformationGradient(u)
        return self.material.CauchyStress(F, p)

    def GreenLagrangeStrain(self):
        u, p = self.state.split(deepcopy=True)
        F = kinematics.DeformationGradient(u)
        return kinematics.GreenLagrangeStrain(F)
Пример #28
0
facet_function = dolfin.MeshFunction("size_t", mesh, "data/facet_function.xml")
marker_functions = pulse.MarkerFunctions(ffun=facet_function)

# Markers
with open("data/markers.json", "r") as f:
    markers = json.load(f)

# Fiber
fiber_element = dolfin.VectorElement(
    family="Quadrature",
    cell=mesh.ufl_cell(),
    degree=4,
    quad_scheme="default",
)
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(
Пример #29
0
    "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):
            V = W if W.sub(0).num_sub_spaces() == 0 else W.sub(0)
            return [
                DirichletBC(V, zero, xlow),
                DirichletBC(V, x, xhigh),
            ]
Пример #30
0
try:
    from dolfin_adjoint import Constant, DirichletBC, Function, Mesh, interpolate
except ImportError:
    from dolfin import Function, Constant, DirichletBC, Mesh, interpolate

gamma_space = "R_0"

geometry = pulse.HeartGeometry.from_file(pulse.mesh_paths["simple_ellipsoid"])
# geometry = pulse.geometries.prolate_ellipsoid_geometry(mesh_size_factor=3.0)

if gamma_space == "regional":
    activation = pulse.RegionalParameter(geometry.cfun)
    target_activation = pulse.dolfin_utils.get_constant(0.2, len(activation))
else:
    activation = Function(dolfin.FunctionSpace(geometry.mesh, "R", 0))
    target_activation = Constant(0.2)

matparams = pulse.HolzapfelOgden.default_parameters()
material = pulse.HolzapfelOgden(
    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")