Source code for ufl.core.interpolate

"""This module defines the Interpolate class."""

# Copyright (C) 2021 Nacime Bouziani
#
# This file is part of UFL (https://www.fenicsproject.org)
#
# SPDX-License-Identifier:    LGPL-3.0-or-later
#
# Modified by Nacime Bouziani, 2021-2022

from ufl.action import Action
from ufl.argument import Argument, Coargument
from ufl.coefficient import Cofunction
from ufl.constantvalue import as_ufl
from ufl.core.base_form_operator import BaseFormOperator
from ufl.core.ufl_type import ufl_type
from ufl.duals import is_dual
from ufl.form import BaseForm, Form
from ufl.functionspace import AbstractFunctionSpace


[docs]@ufl_type(num_ops="varying", is_differential=True) class Interpolate(BaseFormOperator): """Symbolic representation of the interpolation operator.""" # Slots are disabled here because they cause trouble in PyDOLFIN # multiple inheritance pattern: _ufl_noslots_ = True def __init__(self, expr, v): """Initialise. Args: expr: a UFL expression to interpolate. v: the FunctionSpace to interpolate into or the Coargument defined on the dual of the FunctionSpace to interpolate into. """ # This check could be more rigorous. dual_args = (Coargument, Cofunction, Form, Action, BaseFormOperator) if isinstance(v, AbstractFunctionSpace): if is_dual(v): raise ValueError("Expecting a primal function space.") v = Argument(v.dual(), 0) elif not isinstance(v, dual_args): raise ValueError( "Expecting the second argument to be FunctionSpace, FiniteElement or dual." ) expr = as_ufl(expr) if isinstance(expr, dual_args): raise ValueError("Expecting the first argument to be primal.") # Reversed order convention argument_slots = (v, expr) # Get the primal space (V** = V) if isinstance(v, BaseForm): arg, *_ = v.arguments() function_space = arg.ufl_function_space() else: function_space = v.ufl_function_space().dual() # Set the operand as `expr` for DAG traversal purpose. operand = expr BaseFormOperator.__init__( self, operand, function_space=function_space, argument_slots=argument_slots ) def _ufl_expr_reconstruct_(self, expr, v=None, **add_kwargs): """Return a new object of the same type with new operands.""" v = v or self.argument_slots()[0] return type(self)(expr, v, **add_kwargs) def __repr__(self): """Default repr string construction for Interpolate.""" r = "Interpolate(" r += ", ".join(repr(arg) for arg in reversed(self.argument_slots())) r += f"; {self.ufl_function_space()!r})" return r def __str__(self): """Default str string construction for Interpolate.""" s = "Interpolate(" s += ", ".join(str(arg) for arg in reversed(self.argument_slots())) s += f"; {self.ufl_function_space()})" return s def __eq__(self, other): """Check for equality.""" if self is other: return True return ( type(self) is type(other) and all(a == b for a, b in zip(self._argument_slots, other._argument_slots)) and self.ufl_function_space() == other.ufl_function_space() )
# Helper function
[docs]def interpolate(expr, v): """Create symbolic representation of the interpolation operator. Args: expr: a UFL expression to interpolate. v: the FunctionSpace to interpolate into or the Coargument defined on the dual of the FunctionSpace to interpolate into. """ return Interpolate(expr, v)