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