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
Exemple #2
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
    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
    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 normalize_vector_field(u):
    """Given a vector field, return a vector field with an L2 norm equal to 1.0"""
    dim = len(u)
    S = u.function_space().sub(0).collapse()

    components = vectorfield_to_components(u, S, dim)

    normarray = np.sqrt(
        sum(components[i].vector().norm("l2")**2 for i in range(dim)))

    for comp in components:
        comp.vector()[:] = comp.vector() / normarray

    assigners = [
        FunctionAssigner(u.function_space().sub(i), S) for i in range(dim)
    ]
    for i, comp, assigner in zip(range(dim), components, assigners):
        assigner.assign(u.split()[i], comp)

    return u