diff --git a/test/test_interpolate.py b/test/test_interpolate.py index 877f55a35..1aa8b2d17 100644 --- a/test/test_interpolate.py +++ b/test/test_interpolate.py @@ -10,6 +10,7 @@ Adjoint, Argument, Coefficient, + Cofunction, FunctionSpace, Mesh, TestFunction, @@ -69,6 +70,20 @@ def test_symbolic(V1, V2): assert Iu.ufl_operands == (u,) +def test_symbolic_adjoint(V1, V2): + # Set dual of V2 + V2_dual = V2.dual() + + u = Argument(V1, 1) + vstar = Cofunction(V2_dual) + Iu = Interpolate(u, vstar) + + assert Iu.ufl_function_space() == V2_dual + assert Iu.argument_slots() == (vstar, u) + assert Iu.arguments() == (u,) + assert Iu.ufl_operands == (u,) + + def test_action_adjoint(V1, V2): # Set dual of V2 V2_dual = V2.dual() diff --git a/ufl/core/base_form_operator.py b/ufl/core/base_form_operator.py index da28bd5be..9cb28cc1d 100644 --- a/ufl/core/base_form_operator.py +++ b/ufl/core/base_form_operator.py @@ -147,7 +147,7 @@ def ufl_function_space(self): arg, *_ = self.argument_slots() if not isinstance(arg, BaseCoefficient) and isinstance(arg, (BaseForm, Coargument)): arg, *_ = arg.arguments() - return arg._ufl_function_space + return arg.ufl_function_space() def _ufl_expr_reconstruct_( self, *operands, function_space=None, derivatives=None, argument_slots=None diff --git a/ufl/core/interpolate.py b/ufl/core/interpolate.py index 3b5e3ba4d..79a75cc2a 100644 --- a/ufl/core/interpolate.py +++ b/ufl/core/interpolate.py @@ -8,14 +8,12 @@ # # 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.form import BaseForm from ufl.functionspace import AbstractFunctionSpace @@ -35,8 +33,7 @@ def __init__(self, expr, v): 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) + dual_args = (Coargument, BaseForm) if isinstance(v, AbstractFunctionSpace): if is_dual(v): @@ -44,7 +41,7 @@ def __init__(self, expr, v): v = Argument(v.dual(), 0) elif not isinstance(v, dual_args): raise ValueError( - "Expecting the second argument to be FunctionSpace, FiniteElement or dual." + "Expecting the second argument to be FunctionSpace, Coargument, or BaseForm." ) expr = as_ufl(expr) @@ -54,11 +51,9 @@ def __init__(self, expr, v): # 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() + arg, *_ = v.arguments() + function_space = arg.ufl_function_space() + # Set the operand as `expr` for DAG traversal purpose. operand = expr BaseFormOperator.__init__(