def adjoint(form, reordered_arguments=None, adjoint_arguments=None):
    """
    Wrapper for the DOLFIN adjoint function. Accepts the additional optional
    adjoint_arguments, which if supplied should be a tuple of Argument s
    corresponding to the adjoint test and trial functions.
    """

    if adjoint_arguments is None:
        a_form = dolfin.adjoint(form, reordered_arguments=reordered_arguments)
    elif not reordered_arguments is None:
        raise InvalidArgumentException(
            "Cannot supply both reordered_arguments and adjoint_arguments keyword arguments"
        )
    else:
        if not len(adjoint_arguments) == 2 \
          or not isinstance(adjoint_arguments[0], ufl.argument.Argument) \
          or not isinstance(adjoint_arguments[1], ufl.argument.Argument):
            raise InvalidArgumentException(
                "adjoint_arguments must be a pair of Argument s")

        a_test, a_trial = adjoint_arguments
        a_form = dolfin.adjoint(form)
        test, trial = extract_test_and_trial(a_form)

        if not test.element() == a_test.element() or not trial.element(
        ) == a_trial.element():
            raise InvalidArgumentException("Invalid adjoint_arguments")
        a_form = dolfin.replace(a_form, {test: a_test, trial: a_trial})

    return a_form
示例#2
0
def differentiate_expr(expr, u, expand = True):
    """
    Wrapper for the UFL derivative function. This chooses an argument equal to
    Constant(1.0). Form s should be differentiated using the derivative function.
    """

    if not isinstance(expr, ufl.expr.Expr):
        raise InvalidArgumentException("expr must be an Expr")
    if isinstance(u, ufl.indexed.Indexed):
        op = u.operands()
        assert(len(op) == 2)
        if not isinstance(op[0], (dolfin.Constant, dolfin.Function)):
            raise InvalidArgumentException("Invalid Indexed")
    elif not isinstance(u, (dolfin.Constant, dolfin.Function)):
        raise InvalidArgumentException("u must be an Indexed, Constant, or Function")

    if expr is u:
        der = ufl.constantvalue.IntValue(1)
    else:
        unity = dolfin.Constant(1.0)
        der = dolfin.replace(ufl.derivative(expr, u, argument = unity), {unity:ufl.constantvalue.IntValue(1)})

        if expand:
            # Based on code from expand_derivatives1 in UFL file ad.py, (see e.g. bzr
            # 1.1.x branch revision 1484)
            cell = der.cell()
            if cell is None:
                dim = 0
            else:
                dim = der.cell().geometric_dimension()
            der = ufl.algorithms.expand_derivatives(der, dim = dim)

    return der
示例#3
0
def differentiate_expr(expr, u, expand = True):
    """
    Wrapper for the UFL derivative function. This chooses an argument equal to
    Constant(1.0). Form s should be differentiated using the derivative function.
    """

    if not isinstance(expr, ufl.core.expr.Expr):
        raise InvalidArgumentException("expr must be an Expr")
    if isinstance(u, ufl.indexed.Indexed):
        op = u.operands()
        assert(len(op) == 2)
        if not isinstance(op[0], (dolfin.Constant, dolfin.Function)):
            raise InvalidArgumentException("Invalid Indexed")
    elif not isinstance(u, (dolfin.Constant, dolfin.Function)):
        raise InvalidArgumentException("u must be an Indexed, Constant, or Function")

    if expr is u:
        der = ufl.constantvalue.IntValue(1)
    else:
        unity = dolfin.Constant(1.0)
        der = dolfin.replace(ufl.derivative(expr, u, argument = unity), {unity:ufl.constantvalue.IntValue(1)})

        if expand:
            # Based on code from expand_derivatives1 in UFL file ad.py, (see e.g. bzr
            # 1.1.x branch revision 1484)
            cell = der.cell()
            if cell is None:
                dim = 0
            else:
                dim = der.cell().geometric_dimension()
            der = ufl.algorithms.expand_derivatives(der, dim = dim)

    return der
                def __init__(selfmat, *args, **kwargs):
                    if 'initial_guess' in kwargs:
                        selfmat.initial_guess = kwargs['initial_guess']
                        del kwargs['initial_guess']
                    else:
                        selfmat.initial_guess = None

                    replace_map = kwargs['replace_map']
                    del kwargs['replace_map']

                    adjlinalg.Matrix.__init__(selfmat, *args, **kwargs)

                    selfmat.adjoint = kwargs['adjoint']
                    if P is None:
                        selfmat.operators = (dolfin.replace(A, replace_map), None)
                    else:
                        selfmat.operators = (dolfin.replace(A, replace_map), dolfin.replace(P, replace_map))
示例#5
0
                def __init__(self, *args, **kwargs):
                    if 'initial_guess' in kwargs:
                        self.initial_guess = kwargs['initial_guess']
                        del kwargs['initial_guess']
                    else:
                        self.initial_guess = None

                    replace_map = kwargs['replace_map']
                    del kwargs['replace_map']

                    adjlinalg.Matrix.__init__(self, *args, **kwargs)

                    self.adjoint = kwargs['adjoint']
                    if P is None:
                        self.operators = (dolfin.replace(A, replace_map), None)
                    else:
                        self.operators = (dolfin.replace(A, replace_map),
                                          dolfin.replace(P, replace_map))
def unwrap_fns(form):
    """
    Return a form with all WrappedFunction s unwrapped.
    """

    repl = {}
    for dep in ufl.algorithms.extract_coefficients(form):
        if isinstance(dep, WrappedFunction):
            repl[dep] = dep.fn()

    return dolfin.replace(form, repl)
def matrix_optimisation(form):
    """
    Attempt to convert a linear form into the action of a bi-linear form.
    Return a (bi-linear Form, Function) pair on success, and None on failure.
    """

    if not isinstance(form, ufl.form.Form):
        raise InvalidArgumentException("form must be a Form")

    # Find the test function
    args = ufl.algorithms.extract_arguments(form)
    if not len(args) == 1:
        # This is not a linear form
        return None

    # Look for a single non-static Function dependency
    tcs = extract_non_static_coefficients(form)
    if not len(tcs) == 1:
        # Found too many non-static coefficients
        return None
    elif not isinstance(tcs[0], dolfin.Function):
        # The only non-static coefficient is not a Function
        return None
    # Found a single non-static Function dependency
    fn = tcs[0]

    # Look for a static bi-linear form whose action can be used to construct
    # the linear form
    mat_form = derivative(
        form,
        fn,
        # Hack to work around an obscure FEniCS bug
        expand=dolfin.MPI.size(dolfin.mpi_comm_world()) == 1
        or (not is_r0_function_space(args[0].function_space())
            and not is_r0_function(fn)))
    if n_non_static_coefficients(mat_form) > 0:
        # The form is non-linear
        return None
    try:
        rhs_form = dolfin.rhs(
            dolfin.replace(form,
                           {fn: dolfin.TrialFunction(fn.function_space())}))
    except ufl.log.UFLException:
        # The form might be inhomogeneous
        return None
    if not is_empty_form(rhs_form):
        # The form might be inhomogeneous
        return None

    # Success
    return mat_form, fn
def replace(e, mapping):
    """
    Wrapper for the DOLFIN replace function. Correctly handles QForm s.
    """

    if not isinstance(mapping, dict):
        raise InvalidArgumentException("mapping must be a dictionary")

    if len(mapping) == 0:
        return e

    ne = dolfin.replace(e, mapping)
    if isinstance(e, QForm):
        return QForm(ne, quadrature_degree = form_quadrature_degree(e))
    else:
        return ne
示例#9
0
def is_self_adjoint_form(form):
    """
    Return True if the supplied Form is self-adjoint. May return false negatives.
    """

    if not isinstance(form, ufl.form.Form):
        raise InvalidArgumentException("form must be a Form")

    a_form = dolfin.adjoint(form)

    test, trial = extract_test_and_trial(form)
    a_test, a_trial = extract_test_and_trial(a_form)

    if not test.element() == a_trial.element():
        return False
    elif not trial.element() == a_test.element():
        return False

    a_form = dolfin.replace(a_form, {a_test:trial, a_trial:test})

    return expand(form) == expand(a_form)
示例#10
0
def is_self_adjoint_form(form):
    """
    Return True if the supplied Form is self-adjoint. May return false negatives.
    """

    if not isinstance(form, ufl.form.Form):
        raise InvalidArgumentException("form must be a Form")

    a_form = dolfin.adjoint(form)

    test, trial = extract_test_and_trial(form)
    a_test, a_trial = extract_test_and_trial(a_form)

    if not test.element() == a_trial.element():
        return False
    elif not trial.element() == a_test.element():
        return False

    a_form = dolfin.replace(a_form, {a_test:trial, a_trial:test})

    return expand(form) == expand(a_form)
    def match_tensor(self, tensor=None):
        """
        Addition of GenericMatrix s can be more efficient if the sparsity patterns
        match. Extend the sparsity pattern of the input GenericMatrix and any
        relevant internally stored GenericMatrix so that their sparsity patterns
        match. Return the expanded GenericMatrix if tensor is not None. Otherwise
        return a copy of an internal GenericMatrix if one exists, or None otherwise.
        Must be called after the pre_assemble method.

        Arguments:
          tensor: The GenericMatrix whose sparsity pattern is to match any relevant
                  internally stored GenericMatrix s.
        """

        if self._n == 0:
            return tensor
        elif not self._rank == 2:
            raise StateException("Unexpected form rank: %i" % self._rank)
        if not tensor is None and not isinstance(tensor, dolfin.GenericMatrix):
            raise InvalidArgumentException("tensor must be a GenericMatrix")

        one = dolfin.Constant(1.0)
        form = dolfin.replace(
            self._form,
            {c: one
             for c in ufl.algorithms.extract_coefficients(self._form)})
        if self._rank == 1:
            tensor = self._assemble(form)
        elif self._rank == 2:
            if self.__tensor is None:
                self.__tensor = self._assemble(form)
            if tensor is None:
                tensor = self.__tensor.copy()
            else:
                self.__tensor.axpy(0.0, tensor, False)
                tensor.axpy(0.0, self.__tensor, False)
        else:
            raise StateException("Unexpected form rank: %i" % self._rank)

        return tensor