Esempio n. 1
0
def increase_order(V: function.FunctionSpace) -> function.FunctionSpace:
    """For a given function space, return the same space, but with
    polynomial degree increase by 1.

    """
    e = ufl.algorithms.elementtransformations.increase_order(V.ufl_element())
    return function.FunctionSpace(V.mesh(), e)
Esempio n. 2
0
def create_cg1_function_space(mesh, sh):
    r = len(sh)
    if r == 0:
        V = function.FunctionSpace(mesh, ("CG", 1))
    elif r == 1:
        V = function.VectorFunctionSpace(mesh, ("CG", 1), dim=sh[0])
    else:
        V = function.TensorFunctionSpace(mesh, ("CG", 1), shape=sh)
    return V
Esempio n. 3
0
def change_regularity(V: function.FunctionSpace,
                      family: str) -> function.FunctionSpace:
    """For a given function space, return the corresponding space with
    the finite elements specified by 'family'. Possible families are
    the families supported by the form compiler

    """
    e = ufl.algorithms.elementtransformations.change_regularity(
        V.ufl_element(), family)
    return function.FunctionSpace(V.mesh(), e)
Esempio n. 4
0
def _extract_function_space(expression, mesh):
    """Try to extract a suitable function space for projection of given
    expression.

    """

    # Get mesh from expression
    if mesh is None:
        domain = expression.ufl_domain()
        if domain is not None:
            mesh = domain.ufl_cargo()

    # Extract mesh from functions
    if mesh is None:
        # (Not sure if this code is relevant anymore, the above code
        # should cover this)
        # Extract functions
        functions = ufl.algorithms.extract_coefficients(expression)
        for f in functions:
            if isinstance(f, function.Function):
                mesh = f.function_space().mesh
                if mesh is not None:
                    break

    if mesh is None:
        raise RuntimeError(
            "Unable to project expression, cannot find a suitable mesh.")

    # Create function space
    shape = expression.ufl_shape
    if shape == ():
        V = function.FunctionSpace(mesh, ("Lagrange", 1))
    elif len(shape) == 1:
        V = function.VectorFunctionSpace(mesh, ("Lagrange", 1), dim=shape[0])
    elif len(shape) == 2:
        V = function.TensorFunctionSpace(mesh, ("Lagrange", 1), shape=shape)
    else:
        raise RuntimeError("Unhandled rank, shape is {}.".format((shape, )))

    return V
Esempio n. 5
0
def project(v, V=None, bcs=[], mesh=None, funct=None):
    """Return projection of given expression *v* onto the finite element
    space *V*.

    *Arguments*
        v
            a :py:class:`Function <dolfin.functions.function.Function>` or
            an :py:class:`Expression <dolfin.functions.expression.Expression>`
        bcs
            Optional argument :py:class:`list of DirichletBC
            <dolfin.fem.bcs.DirichletBC>`
        V
            Optional argument :py:class:`FunctionSpace
            <dolfin.functions.functionspace.FunctionSpace>`
        mesh
            Optional argument :py:class:`mesh <dolfin.cpp.Mesh>`.
        funct
            Target function where result is stored.

    *Example of usage*

        .. code-block:: python

            v = Expression("sin(pi*x[0])")
            V = FunctionSpace(mesh, "Lagrange", 1)
            Pv = project(v, V)

        This is useful for post-processing functions or expressions
        which are not readily handled by visualization tools (such as
        for example discontinuous functions).

    """

    # Try figuring out a function space if not specified
    if V is None:
        # Create function space based on Expression element if trying
        # to project an Expression
        if isinstance(v, function.Expression):
            if mesh is not None and isinstance(mesh, cpp.mesh.Mesh):
                V = function.FunctionSpace(mesh, v.ufl_element())
            # else:
            #     cpp.dolfin_error("projection.py",
            #                      "perform projection",
            #                      "Expected a mesh when projecting an Expression")
        else:
            # Otherwise try extracting function space from expression
            V = _extract_function_space(v, mesh)

    # Check arguments

    # Ensure we have a mesh and attach to measure
    if mesh is None:
        mesh = V.mesh
    dx = ufl.dx(mesh)

    # Define variational problem for projection
    w = function.TestFunction(V)
    Pv = function.TrialFunction(V)
    a = ufl.inner(Pv, w) * dx
    L = ufl.inner(v, w) * dx

    # Assemble linear system
    A = fem.assemble_matrix(a, bcs)
    A.assemble()
    b = fem.assemble_vector(L)
    fem.apply_lifting(b, [a], [bcs])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    fem.set_bc(b, bcs)

    # Solve linear system for projection
    if funct is None:
        funct = function.Function(V)
    la.solve(A, funct.vector, b)

    return funct
Esempio n. 6
0
def project(v,
            V=None,
            bcs=None,
            mesh=None,
            function=None,
            solver_type="lu",
            preconditioner_type="default",
            form_compiler_parameters=None):
    """Return projection of given expression *v* onto the finite element
    space *V*.

    *Arguments*
        v
            a :py:class:`Function <dolfin.functions.function.Function>` or
            an :py:class:`Expression <dolfin.functions.expression.Expression>`
        bcs
            Optional argument :py:class:`list of DirichletBC
            <dolfin.fem.bcs.DirichletBC>`
        V
            Optional argument :py:class:`FunctionSpace
            <dolfin.functions.functionspace.FunctionSpace>`
        mesh
            Optional argument :py:class:`mesh <dolfin.cpp.Mesh>`.
        solver_type
            see :py:func:`solve <dolfin.fem.solving.solve>` for options.
        preconditioner_type
            see :py:func:`solve <dolfin.fem.solving.solve>` for options.
        form_compiler_parameters
            see :py:class:`Parameters <dolfin.cpp.Parameters>` for more
            information.

    *Example of usage*

        .. code-block:: python

            v = Expression("sin(pi*x[0])")
            V = FunctionSpace(mesh, "Lagrange", 1)
            Pv = project(v, V)

        This is useful for post-processing functions or expressions
        which are not readily handled by visualization tools (such as
        for example discontinuous functions).

    """

    # Try figuring out a function space if not specified
    if V is None:
        # Create function space based on Expression element if trying
        # to project an Expression
        if isinstance(v, function.Expression):
            if mesh is not None and isinstance(mesh, cpp.mesh.Mesh):
                V = function.FunctionSpace(mesh, v.ufl_element())
            # else:
            #     cpp.dolfin_error("projection.py",
            #                      "perform projection",
            #                      "Expected a mesh when projecting an Expression")
        else:
            # Otherwise try extracting function space from expression
            V = _extract_function_space(v, mesh)

    # Check arguments

    # Ensure we have a mesh and attach to measure
    if mesh is None:
        mesh = V.mesh()
    dx = ufl.dx(mesh)

    # Define variational problem for projection
    w = function.TestFunction(V)
    Pv = function.TrialFunction(V)
    a = ufl.inner(w, Pv) * dx
    L = ufl.inner(w, v) * dx

    # Assemble linear system
    A, b = fem.assemble_system(
        a, L, bcs=bcs, form_compiler_parameters=form_compiler_parameters)

    # Solve linear system for projection
    if function is None:
        function = function.Function(V)
    la.solve(A, function.vector(), b, solver_type, preconditioner_type)

    return function