Skip to content

p-multigrid: remove custom interpolation code - #5289

Open
pbrubeck wants to merge 13 commits into
mainfrom
pbrubeck/remove-pmg-parloop
Open

p-multigrid: remove custom interpolation code#5289
pbrubeck wants to merge 13 commits into
mainfrom
pbrubeck/remove-pmg-parloop

Conversation

@pbrubeck

@pbrubeck pbrubeck commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Stack

Merge in this order, each PR retargets to main once the one above it lands:

# PR what
1 firedrakeproject/fiat#271 FInAT: select H(div)/H(curl) components with a Delta
2 firedrakeproject/fiat#268 FInAT: dual evaluate on each sub-element's own points
3 #5289 p-multigrid: remove custom interpolation

Removes ~1050 lines of hand-written interpolation machinery from
firedrake/preconditioners/pmg.pyStandaloneInterpolationMatrix,
MixedInterpolationMatrix, kronmxv, get_permutation_to_nodal_elements,
evaluate_dual and friends — and replaces the p-multigrid transfer operators with
the generic assemble(interpolate(TrialFunction(cV), fV)). The helpers that are still
needed move to firedrake/preconditioners/fdm.py.

Depends on firedrakeproject/fiat#268

Fixes #5391 by removing the transfer matrix cache

🤖 Generated with Claude Code

Comment thread firedrake/interpolation.py Outdated
Comment thread firedrake/interpolation.py Outdated
Comment thread firedrake/interpolation.py Outdated
@pbrubeck
pbrubeck force-pushed the pbrubeck/remove-pmg-parloop branch from 8b84e62 to 41c33c8 Compare July 29, 2026 18:30
@pbrubeck
pbrubeck force-pushed the pbrubeck/fix/dual-enriched branch 2 times, most recently from 168ee7b to 6072eee Compare July 29, 2026 23:29
@pbrubeck
pbrubeck force-pushed the pbrubeck/remove-pmg-parloop branch from 3d81cdf to 33be7ba Compare July 29, 2026 23:29
@pbrubeck
pbrubeck changed the base branch from pbrubeck/fix/dual-enriched to pbrubeck/hdivcurl-delta July 29, 2026 23:33
@pbrubeck
pbrubeck force-pushed the pbrubeck/hdivcurl-delta branch from a992610 to 537d1b5 Compare August 18, 2026 22:22
@pbrubeck
pbrubeck force-pushed the pbrubeck/remove-pmg-parloop branch from 2cdcc16 to 59e617b Compare August 18, 2026 22:22
Comment thread firedrake/functionspaceimpl.py Outdated
Comment thread firedrake/functionspaceimpl.py Outdated
@pbrubeck
pbrubeck force-pushed the pbrubeck/remove-pmg-parloop branch from e9e3a1e to 59e617b Compare August 24, 2026 22:24
pbrubeck and others added 5 commits August 26, 2026 12:44
An element whose functionals do not all evaluate on the same points is a
direct sum, and has a dual basis only on each of its sub-elements, not one
weight tensor on one point set.  Reconstructing it as a runtime Quadrature
space only ever wanted the points, so ask for those directly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Assembling a two-form Interpolate matrix-free passed the same bcs as both
the row and the column bcs of the ImplicitMatrixContext, and left on_diag
at its default of True.  Neither holds for interpolation between two
different spaces: applying the target space's bcs to the source side
raised "Cofunction defined on incompatible FunctionSpace", and on_diag
made multTranspose try to write the row values into the column vector.

Split the bcs by the space they are defined on, as the assembled path
already does, and set on_diag from whether the two spaces coincide.  A bc
on a component of a mixed space is defined on an IndexedProxyFunctionSpace
rather than on the space itself, so compare against the top-level parent,
which BCBase.function_space now returns on request.

Coarsen the p-multigrid nullspace with a locally built interpolation
matrix, rather than through getNestSubMatrix, which only the removed
MixedInterpolationMatrix provided.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pbrubeck
pbrubeck force-pushed the pbrubeck/remove-pmg-parloop branch from 57c801d to fc8c4f9 Compare August 26, 2026 11:46
@pbrubeck
pbrubeck changed the base branch from pbrubeck/hdivcurl-delta to main August 26, 2026 11:46
Installs firedrakeproject/fiat@pbrubeck/fix/dual-enriched over the pinned
FIAT, so CI gets fiat#268 and the fiat#271 it sits on. This PR needs the
dual evaluation those provide.

Drop once fiat#271 and fiat#268 land on FIAT main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pbrubeck
pbrubeck force-pushed the pbrubeck/remove-pmg-parloop branch from fc8c4f9 to 8b12202 Compare August 26, 2026 11:58
Comment thread firedrake/functionspaceimpl.py Outdated
@pbrubeck
pbrubeck requested a review from connorjward August 26, 2026 15:34

ibase = numpy.arange(bsize, dtype=node_map.values.dtype)
return partial(vector_map, bsize, ibase), nel

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 is custom code from pmg.py that is now only required by fdm.py

@pbrubeck pbrubeck added the LLM used An LLM was used in the production of this PR label Aug 26, 2026
The dual basis of a restricted element is a Concatenate, and a Cofunction
dual argument sums over the index that concatenates it.  Forming that
contraction first leaves the Concatenate indexed by a reduction index that
no assignment variable carries, so unconcatenate has nothing to split it
against and it reaches argument factorisation, which cannot break it up.

Split the pair of the dual coefficient and the tabulation first, as
assembly already does for coefficient evaluation, and contract each block
over the basis indices of its own block.

Interpolating between facet-restricted spaces, as p-multigrid does under
FacetSplitPC, raised FactorisationError before this.  The error escaped a
PETSc callback, which left the preconditioner half built, and destroying it
later segfaulted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@connorjward

Copy link
Copy Markdown
Contributor

This is failing an awful lot of tests. Is it ready for review?

@pbrubeck

Copy link
Copy Markdown
Contributor Author

This is failing an awful lot of tests. Is it ready for review?

I'll be fixing those today. I'll ask for review when it's passing. In principle it should be a small fix to make everything pass

@connorjward

Copy link
Copy Markdown
Contributor

Can you check if this fixes #5391? I just debugged that down to it being (I think) to do with StandaloneInterpolationMatrix.

pbrubeck and others added 2 commits August 27, 2026 10:23
Every worker of the `tests/tsfc` session segfaults at its first
`compile_form`, in `petsctools.cite` -> `PETSc.Sys.registerCitation`, because
`PetscCitationsList` is still NULL: PETSc was never initialised.

`petsc4py.lib.ImportPETSc` puts the extension module straight into
`sys.modules`, bypassing the `petsc4py/PETSc.py` shim that calls
`PETSc._initialize`.  Once that has happened no later `from petsc4py import
PETSc` initialises anything.  The same fingerprint shows in the firedrake
sessions: on `main` the conftest's `import pyadjoint` initialises PETSc
before `firedrake/__init__.py` does, and `petsctools.init` warns that it is
too late; on this branch that warning never appears.

This does not reproduce locally, so record who calls `ImportPETSc` and report
the state of PETSc once collection has imported every test module.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pbrubeck

Copy link
Copy Markdown
Contributor Author

Can you check if this fixes #5391? I just debugged that down to it being (I think) to do with StandaloneInterpolationMatrix.

It does fix it.

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

Labels

base:main Run this PR using a main (dev) build LLM used An LLM was used in the production of this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: PMGPC keeps every mesh alive, so memory grows without bound when solvers are built in a loop

3 participants