Skip to content

form splitter: use DAGTraverser and handle Action, Adjoint - #5484

Open
leo-collins wants to merge 16 commits into
mainfrom
leo/formsplitter-dagtraverser
Open

leo-collins wants to merge 16 commits into
mainfrom
leo/formsplitter-dagtraverser

Conversation

@leo-collins

@leo-collins leo-collins commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Makes the split_form MultiFunction be a DAGTraverser.

Also handles splitting Adjoints and Actions. Previously, something like

W = V * V
u, _ = TrialFunctions(W)
I = interpolate(u, V)
c = Cofunction(V.dual())
F = action(adjoint(I), c)
split_form(F)

would fail because F has a single argument numbered 0, but the inner Interpolate has an argument numbered 1, so ExtractSubBlock would try to select a non-existant block.

For Adjoint, we swap the row and columns, for Action we need to maintain the argument that gets contracted out.

@pbrubeck

Copy link
Copy Markdown
Contributor

This is great. Should we consider migrating this to ufl?

Comment thread firedrake/formmanipulation.py Outdated
Comment thread firedrake/formmanipulation.py
Comment thread firedrake/formmanipulation.py
Comment thread firedrake/formmanipulation.py Outdated
Comment thread firedrake/formmanipulation.py Outdated
Comment thread firedrake/formmanipulation.py Outdated
Comment thread firedrake/formmanipulation.py Outdated
Comment thread firedrake/formmanipulation.py
@pbrubeck

Copy link
Copy Markdown
Contributor

This is great. Should we consider migrating this to ufl?

Splitting a Function might be the only real blocker because we do things with MixedDat.

indices = self.select_block(blocks, a.number())
if indices is None or len(a.function_space()) == 1:
return a
return Argument.reconstruct(a, function_space=subspace(a.function_space(), indices))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return Argument.reconstruct(a, function_space=subspace(a.function_space(), indices))
return a.reconstruct(function_space=subspace(a.function_space(), indices))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This called the Firedrake Argument reconstruct which complains about the value shape not matching

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be tempted to remove that check

Comment thread firedrake/formmanipulation.py Outdated
return ZeroBaseForm(tuple(map(self, o.arguments())))
@process.register(ZeroBaseForm)
def _(self, o, blocks):
return ZeroBaseForm(tuple(self._subspace_argument(a, blocks) for a in o.arguments()))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can we not map(self) anymore?

@pbrubeck pbrubeck Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DAGTraverser.__call__ is doing something else?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blocks is no longer an attribute on self, so we have to pass it down. Before, _subspace_argument() was called in the split() method when handling a ZeroBaseForm.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this works

from itertools import repeat

map(self, o.arguments(), repeat(blocks))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calling self on the arguments would return a split argument. ZeroBaseForm needs unsplit arguments on the subspaces.

@pbrubeck

Copy link
Copy Markdown
Contributor

I resolved a merge conflict after #4093 got merged

Comment thread firedrake/formmanipulation.py Outdated
@pbrubeck
pbrubeck added this pull request to stack #5489 September 25, 2026 17:44

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants