Beispiel #1
0
def compute_form_with_arity(form, arity, arguments=None):
    """Compute parts of form of given arity."""

    # Extract all arguments in form
    if arguments is None:
        arguments = form.arguments()

    parts = [arg.part() for arg in arguments]
    if set(parts) - {None}:
        error("compute_form_with_arity cannot handle parts.")

    if len(arguments) < arity:
        warning("Form has no parts with arity %d." % arity)
        return 0*form

    # Assuming that the form is not a sum of terms
    # that depend on different arguments, e.g. (u+v)*dx
    # would result in just v*dx. But that doesn't make
    # any sense anyway.
    sub_arguments = set(arguments[:arity])
    pe = PartExtracter(sub_arguments)

    def _transform(e):
        e, provides = pe.visit(e)
        if provides == sub_arguments:
            return e
        return Zero()
    return map_integrands(_transform, form)
Beispiel #2
0
def compute_form_with_arity(form, arity, arguments=None):
    """Compute parts of form of given arity."""

    # Extract all arguments in form
    if arguments is None:
        arguments = form.arguments()

    parts = [arg.part() for arg in arguments]
    if set(parts) - {None}:
        error("compute_form_with_arity cannot handle parts.")

    if len(arguments) < arity:
        warning("Form has no parts with arity %d." % arity)
        return 0*form

    # Assuming that the form is not a sum of terms
    # that depend on different arguments, e.g. (u+v)*dx
    # would result in just v*dx. But that doesn't make
    # any sense anyway.
    sub_arguments = set(arguments[:arity])
    pe = PartExtracter(sub_arguments)

    def _transform(e):
        e, provides = pe.visit(e)
        if provides == sub_arguments:
            return e
        return Zero()
    return map_integrands(_transform, form)
Beispiel #3
0
def compute_form_adjoint(form, reordered_arguments=None):
    """Compute the adjoint of a bilinear form.

    This works simply by swapping the number and part of the two arguments,
    but keeping their elements and places in the integrand expressions.
    """
    arguments = form.arguments()

    parts = [arg.part() for arg in arguments]
    if set(parts) - {None}:
        error("compute_form_adjoint cannot handle parts.")

    if len(arguments) != 2:
        error("Expecting bilinear form.")

    v, u = arguments
    if v.number() >= u.number():
        error("Mistaken assumption in code!")

    if reordered_arguments is None:
        reordered_u = Argument(u.ufl_function_space(),
                               number=v.number(),
                               part=v.part())
        reordered_v = Argument(v.ufl_function_space(),
                               number=u.number(),
                               part=u.part())
    else:
        reordered_u, reordered_v = reordered_arguments

    if reordered_u.number() >= reordered_v.number():
        error("Ordering of new arguments is the same as the old arguments!")

    if reordered_u.part() != v.part():
        error("Ordering of new arguments is the same as the old arguments!")
    if reordered_v.part() != u.part():
        error("Ordering of new arguments is the same as the old arguments!")

    if reordered_u.ufl_function_space() != u.ufl_function_space():
        error(
            "Element mismatch between new and old arguments (trial functions)."
        )
    if reordered_v.ufl_function_space() != v.ufl_function_space():
        error(
            "Element mismatch between new and old arguments (test functions).")

    return map_integrands(Conj, replace(form, {
        v: reordered_v,
        u: reordered_u
    }))
Beispiel #4
0
def diff(f, v):
    """UFL operator: Take the derivative of *f* with respect to the variable *v*.

    If *f* is a form, ``diff`` is applied to each integrand.
    """
    # Apply to integrands
    if isinstance(f, Form):
        from ufl.algorithms.map_integrands import map_integrands
        return map_integrands(lambda e: diff(e, v), f)

    # Apply to expression
    f = as_ufl(f)
    if isinstance(v, SpatialCoordinate):
        return grad(f)
    elif isinstance(v, (Variable, Coefficient)):
        return VariableDerivative(f, v)
    else:
        error("Expecting a Variable or SpatialCoordinate in diff.")
Beispiel #5
0
def diff(f, v):
    """UFL operator: Take the derivative of *f* with respect to the variable *v*.

    If *f* is a form, ``diff`` is applied to each integrand.
    """
    # Apply to integrands
    if isinstance(f, Form):
        from ufl.algorithms.map_integrands import map_integrands
        return map_integrands(lambda e: diff(e, v), f)

    # Apply to expression
    f = as_ufl(f)
    if isinstance(v, SpatialCoordinate):
        return grad(f)
    elif isinstance(v, (Variable, Coefficient)):
        return VariableDerivative(f, v)
    else:
        error("Expecting a Variable or SpatialCoordinate in diff.")
Beispiel #6
0
def compute_form_adjoint(form, reordered_arguments=None):
    """Compute the adjoint of a bilinear form.

    This works simply by swapping the number and part of the two arguments,
    but keeping their elements and places in the integrand expressions.
    """
    arguments = form.arguments()

    parts = [arg.part() for arg in arguments]
    if set(parts) - {None}:
        error("compute_form_adjoint cannot handle parts.")

    if len(arguments) != 2:
        error("Expecting bilinear form.")

    v, u = arguments
    if v.number() >= u.number():
        error("Mistaken assumption in code!")

    if reordered_arguments is None:
        reordered_u = Argument(u.ufl_function_space(), number=v.number(),
                               part=v.part())
        reordered_v = Argument(v.ufl_function_space(), number=u.number(),
                               part=u.part())
    else:
        reordered_u, reordered_v = reordered_arguments

    if reordered_u.number() >= reordered_v.number():
        error("Ordering of new arguments is the same as the old arguments!")

    if reordered_u.part() != v.part():
        error("Ordering of new arguments is the same as the old arguments!")
    if reordered_v.part() != u.part():
        error("Ordering of new arguments is the same as the old arguments!")

    if reordered_u.ufl_function_space() != u.ufl_function_space():
        error("Element mismatch between new and old arguments (trial functions).")
    if reordered_v.ufl_function_space() != v.ufl_function_space():
        error("Element mismatch between new and old arguments (test functions).")

    return map_integrands(Conj, replace(form, {v: reordered_v, u: reordered_u}))
Beispiel #7
0
def apply_transformer(e, transformer, integral_type=None):
    """Apply transformer.visit(expression) to each integrand
    expression in form, or to form if it is an Expr."""
    return map_integrands(lambda expr: transformer.visit(expr), e,
                          integral_type)