Fix fieldsplit with Cofunction right hand side.#3932
Merged
Conversation
Member
Author
|
@stephankramer I see that you were also having issues with this in thetisproject/thetis#376. If you/someone else from the Thetis team could checkout this branch and make sure it fixes things for you then that would be really helpful. |
|
|
pbrubeck
previously requested changes
Dec 16, 2024
Ig-dolci
reviewed
Dec 16, 2024
Co-authored-by: Pablo Brubeck <brubeck@protonmail.com>
…om/firedrakeproject/firedrake into JHopeCollins/cofunction_fieldsplit
connorjward
requested changes
Dec 19, 2024
pbrubeck
reviewed
Dec 19, 2024
pbrubeck
reviewed
Dec 19, 2024
pbrubeck
reviewed
Dec 19, 2024
Member
Author
|
@pbrubeck unless you have any other issues I'd like to merge this PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem description
As described in #3368, it currently isn't possible to use PCFieldsplit if the form contains a
Cofunction.This is because the way we split the form is by traversing the dag with a
ufl.MultiFunctionand splitting each node as it is visited. However, none of the current handlers will deal with aCofunction.This PR adds a
Cofunctionhandler to theExtractSubBlockmultifunction to do this splitting.Fixes #3368
What does the
Cofunctionhandler need to achieve?A fieldsplit solver needs the right hand side from the corresponding field. For a
Cofunctionthis means the values in the correspondingsubfunction. So when we split a form the return value needs to live in the correct subspace, and point to the numerical values from the full space.How is this implemented?
If all terms in the form have 1 argument (i.e. a
FormSumofCofunctionsand 1-forms), then life is simple. We just check which field(s) is being requested, and make a newCofunctionin that (possibly mixed) subspace using theDatsfrom the originalCofunction.If some terms in the full
Formhave 2 arguments, then life is a little more complicated, and we have two possibilities.If we're being asked for a block on the diagonal, then a) numerically this is probably going to be inverted and so needs a right hand side and b) mathematically this acts on a member of a function space and returns an assembled thing in the dual space - this is exactly what the
Cofunctionis (I'm jetlagged and I've probably slaughtered the dual/primal space technicalities. Edits to fix the explanation welcome). In this case we do the same as for the 1-form case i.e. we just make a new smallerCofunctionthat views the appropriate parts of the fullCofunction.If we're being asked for an off-diagonal block, then a) numerically this doesn't make sense to invert and hence to have a right hand side, and b) mathematically the test and trial spaces are different, which doesn't make sense to have a corresponding
Cofunction(I think?). In this case we just return aZeroBaseFormwhich will get optimised out before we do any actual computational work.Other changes
Because we can now split a
CofunctionorFormSum, not just aForm, I had to widen the logic insplit_formfor checking if the form returned byExtractSubBlockis empty or not. It works but it might not be the best/most robust way of checking.What if this all breaks in the future?
There's a test that solves a mixed formulation of the wave equation using a Schur factorisation with both a 1-form right hand side and an equivalent
Cofunctionright hand side, and checks the results match close to machine precision.The Schur complement is built by asking PETSc to do the brute force thing. Computationally suboptimal but the mesh is tiny, it reduces the amount of other "stuff" needed, and testing implementations is basically what the brute force thing is for.