Ejemplo n.º 1
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
Ejemplo n.º 2
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)
Ejemplo n.º 4
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
Ejemplo n.º 5
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
Ejemplo n.º 6
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")
Ejemplo n.º 7
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
Ejemplo n.º 8
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
Ejemplo n.º 9
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
Ejemplo n.º 10
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
Ejemplo n.º 11
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))
Ejemplo n.º 12
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_)
Ejemplo n.º 13
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)
Ejemplo n.º 14
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)
Ejemplo n.º 15
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
Ejemplo n.º 16
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
Ejemplo 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))
    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 _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)
Ejemplo n.º 20
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)
Ejemplo n.º 21
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
Ejemplo n.º 22
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)
Ejemplo n.º 23
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
Ejemplo n.º 24
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),
            ]
Ejemplo n.º 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]
Ejemplo n.º 26
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(