BUG: interpolating from a Submesh onto its parent zeroes interface dofs in parallel
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 15/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- hpc, python
- Ambito
- distributed-systems
Direzione di ricerca
Start from the reproduction script submesh_interp_repro.py and run it under mpiexec -n 2, where 239 submesh dofs on the x = 0.5 interface read back as 0. The cause is in how the interpolation writes into ghost entries of the parent space when submesh extraction changes dof ownership, so the entry points are the subset= and allow_missing_dofs=True paths of interpolate. Done means the script reports 0 wrong dofs on 2, 3, 4 and 6 ranks, with the result independent of partition.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Describe the bug
Interpolating a Function from a Submesh onto a space on the parent mesh, with interpolate(..., subset=parent.cell_subset(...)) or with allow_missing_dofs=True, is exact in serial. In parallel, some dofs on the boundary of the submesh come back as 0. Which dofs, and how many, depends on the number of ranks and the partition.
As far as we can tell, the cause is that extracting the submesh reassigns dof ownership: a dof on the submesh boundary can be owned by one rank on the submesh and by another on the parent. The rank that owns a submesh cell around the dof writes the correct value, but on the parent that entry may be a ghost. The parent's owner, which only has cells outside the submesh around that dof, writes nothing. Since the interpolation writes rather than accumulates, the owner's 0 then overwrites the ghost value in the halo exchange.
Steps to Reproduce
- Script (
submesh_interp_repro.py): a 12x12x12 unit cube, submesh = the halfx < 0.5, P2 field1 + x + y + z.
import firedrake as fd
from firedrake.petsc import PETSc
mesh = fd.UnitCubeMesh(12, 12, 12)
x = fd.SpatialCoordinate(mesh)
indicator = fd.Function(fd.FunctionSpace(mesh, "DG", 0)).interpolate(fd.conditional(x[0] < 0.5, 1.0, 0.0))
parent = fd.RelabeledMesh(mesh, [indicator], [999])
submesh = fd.Submesh(parent, 3, 999)
V_sub = fd.FunctionSpace(submesh, "CG", 2)
V_parent = fd.FunctionSpace(parent, "CG", 2)
xs = fd.SpatialCoordinate(submesh)
f_sub = fd.Function(V_sub).interpolate(1 + xs[0] + xs[1] + xs[2])
for label, kwargs in [
("subset=", {"subset": parent.cell_subset(999)}),
("allow_missing_dofs=True", {"allow_missing_dofs": True}),
]:
f_parent = fd.assemble(fd.interpolate(f_sub, V_parent, **kwargs))
# Read the parent values back onto the submesh and count the nodes that changed.
round_trip = fd.assemble(fd.interpolate(f_parent, V_sub))
wrong = fd.Function(V_sub).interpolate(fd.conditional(abs(round_trip - f_sub) > 1e-10, 1.0, 0.0))
with wrong.dat.vec_ro as v:
n_wrong = int(v.sum())
PETSc.Sys.Print(f"{mesh.comm.size} ranks, {label}: {n_wrong} of {V_sub.dim()} submesh dofs wrong")
- Command executed:
for n in 1 2 3 4 6; do mpiexec -n $n python submesh_interp_repro.py; done
Output:
1 ranks, subset=: 0 of 8125 submesh dofs wrong
1 ranks, allow_missing_dofs=True: 0 of 8125 submesh dofs wrong
2 ranks, subset=: 239 of 8125 submesh dofs wrong
2 ranks, allow_missing_dofs=True: 239 of 8125 submesh dofs wrong
3 ranks, subset=: 0 of 8125 submesh dofs wrong
3 ranks, allow_missing_dofs=True: 0 of 8125 submesh dofs wrong
4 ranks, subset=: 0 of 8125 submesh dofs wrong
4 ranks, allow_missing_dofs=True: 0 of 8125 submesh dofs wrong
6 ranks, subset=: 7 of 8125 submesh dofs wrong
6 ranks, allow_missing_dofs=True: 7 of 8125 submesh dofs wrong
On 2 ranks, all 239 wrong dofs read back as exactly 0, and they all lie on the x = 0.5 interface. The read-back step is not the culprit: after the accumulate-and-average transfer described below, the same read-back reports 0 wrong dofs.
Expected behavior
The result should not depend on the partition: every dof in the closure of the submesh cells should carry the submesh value on any number of ranks, as it does in serial.
Error message
None: the wrong values are silent.
Environment:
- OS: macOS (Darwin 25.3.0)
- Python version: 3.14.6
- Firedrake 2025.10.4, petsc4py 3.24.3. Also reproduced on Firedrake 2026.4.0.
- MPI: Open MPI 5.0.9
- Relevant packages from
pip list:
firedrake 2025.10.4
firedrake-fiat 2025.10.1
fenics-ufl 2025.2.1
loopy 2025.2
petsc4py 3.24.3
mpi4py 4.1.2
numpy 2.4.4
- No relevant environment variables or modifications
Additional Info
Our workaround: interpolate as usual into a zeroed target, interpolate a field of ones the same way to count how many times each dof is written, sum both onto the owners with dat.local_to_global_begin/end(Access.INC), then divide the values by the counts wherever the count is positive. Every contribution to a given dof carries the same value, so this gives the exact result on any partition. It would be good if the interpolation onto the parent were partition-independent on its own, or, if writing into ghost entries is expected here, if this were documented.
- Lingua principale
- Python
- Stelle
- 684
- Fork
- 204
- Merge medio
- 4g 14h
- PR unite (30g)
- 46
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Nessuna guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di firedrakeproject/firedrake
-
BUG: NonlinearVariationalSolver errors with adj_kwargsForse già presa @dham l’ha presa 151 giorni fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
firedrakeproject/firedrake#5186 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
firedrakeproject/firedrake#5091 ·
I maintainer di solito rispondono entro 1 giorno
-
documentation
Difficoltà 1/5 1-3 ore Idoneità per principianti 82/100
firedrakeproject/firedrake#3556 ·
I maintainer di solito rispondono entro 1 giorno
-
bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 22/100
firedrakeproject/firedrake#5644 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Function.assign on a subset fails with a Constant, a Real Function or abs in the expressionForse già presa @connorjward l’ha presa 2 giorni fa. Aperta
firedrakeproject/firedrake#5643 · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di firedrakeproject/firedrake
Issue simili
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
Sienna-Platform/SiennaSchemas#130 ·
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 85/100
firedrakeproject/Irksome#293 ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
ida-arbeitszeit/workers-control#1578 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
aws-samples/sample-per-model-bedrock#898 ·
I maintainer di solito rispondono entro 1 giorno