Skip to content

Adjoints of coarguments behave inconsistently #395

@dham

Description

@dham

Consider the following code (Firedrake syntax, but the issue is UFL):

from firedrake import *
m = UnitIntervalMesh(2)
V = FunctionSpace(m, "CG", 1)
ca = Coargument(V.dual(), 0)

ca is really the identity operator in $V^{\ast}\rightarrow V^{\ast}$ (equivalently it is a form in $V^{*}\times V \rightarrow R$) and it can arise in adjoint calculations when a variational problem has a pre-assembled cofunction in its RHS. The issue arises when taking the adjoint of ca. Note:

In [10]: adjoint(ca)
Out[10]: Argument(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x106be17f0>, FiniteElement('Lagrange', interval, 1), name=None), Mesh(VectorElement(FiniteElement('Lagrange', interval, 1), dim=1), 0)), 0, None)
In [12]: adjoint(2*ca)
Out[12]: FormSum([2*Argument(WithGeometry(FunctionSpace(<firedrake.mesh.MeshTopology object at 0x106be17f0>, FiniteElement('Lagrange', interval, 1), name=None), Mesh(VectorElement(FiniteElement('Lagrange', interval, 1), dim=1), 0)), 0, None)])

In effect, the adjoint of ca is treated as an unknown Function in V but the adjoint of a scalar multiple of ca is treated as a form in $V^{**}\times V^{*}\rightarrow R$ (equivalently an operator in $V\rightarrow V$). These spaces are mathematically isomorphic, but as a matter of type the former is a UFL expression while the latter is a form. When taking the adjoint of a form we expect to get back another form, so the latter would be preferable. This currently causes some special casing in Firedrake.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions