Redistributed Submesh and MeshHierarchy - #5270
Conversation
|
Is this ready for review? You seem to still be working on it. |
It is ready you can review it, but ideally we should merge #5213 and #5215 first. I'm adding the review suggestions from the meeting, and I have a genuine question: should we introduce a new |
| from pyop2.mpi import MPI | ||
|
|
||
|
|
||
| class RedistributedMeshTransfer: |
There was a problem hiding this comment.
Should we move this to Function.assign()? Maybe we can do it more generalically for Submesh, RestrictedFunctionSpace, and RestributedMesh
There was a problem hiding this comment.
We now can redistribute a Mesh/Submesh. I am only adding support for assign across the submesh and its parent, which is what redistributed multigrid needs.
8e51000 to
f4b9c56
Compare
a55c288 to
2a1e2f6
Compare
An adaptive refinement can leave some ranks with no cells of their own when the marked region is small or clustered, and the same can happen to a uniform MeshHierarchy level on a coarse base mesh. Teach Submesh to redistribute a mesh onto a balanced partition while inheriting the parent's universal vertex numbering and cell orientations, so that the redistributed mesh's nodes stay in one-to-one correspondence with the parent's. MeshHierarchy and refine_marked_elements grow a redistribute= option that, when a level would otherwise have empty ranks, replaces it with such a redistributed Submesh. The transfer operators run on the parent-owned mesh the cell maps were built from and then Assigner moves the result across the point SF relating parent and submesh, via a new Assigner._assign_redistributed path.
Co-authored-by: Pablo Brubeck <brubeck@protonmail.com>
Split the sentences that stack clauses, and say what invalidates the inherited entity classification rather than what stops holding.
Submesh() builds a submesh it does not redistribute with the no-op distribution parameters, and then overwrites them with the parameters of the parent. Say which of the two the condition tests, and why the overwrite is right. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
44b2bb9 to
f233f11
Compare
# Conflicts: # tests/firedrake/multigrid/test_adaptive_multigrid.py
_make_submesh_point_sf pointed every leaf at this rank's copy of the parent point. Where that copy was a ghost, a reduction from the submesh landed in a halo slot that never reached the owner, and the covered mask then discarded it: an assignment onto the parent silently missed those nodes. Name the redistributed sentinel (is_redistributed), the cell-closure guard and the collective emptiness question, and give the coordinate transfer its own two functions so that Mesh() carries the attributes it used to be given afterwards. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GRZG3iuNzgXQWGiuzrjKQo
Stack
PR 3 of 4: #5337 (
fix-dg-injection-child-count) -> #5288 (adaptive-multigrid) -> this PR(
mesh-redistribution) -> #5287 (assign-submesh-restricted).Summary
AI-assisted (Claude Code)
Mesh redistribution is now a
Submeshof the mesh it was redistributed from, rather than an ad-hocredistattribute bolted onto the mesh.Submesh(mesh, redistribute=True)repartitions instead of inheriting the parent's paralleldistribution, for both
subdomain_id=None(the whole mesh, as needed by a redistributedMeshHierarchy) and a proper subdomain (co-dimension 0 only). The child records asubmesh_point_sfpushing the parent's plex points onto its own, whichis_redistributedasksabout;
submesh_shares_distributiontells consumers (assembly, interpolation) whether two relatedmeshes still share a distribution.
vertex numbering (
dmcommon.submesh_vertex_numbering) and quadrilateral/hexahedral cellorientations (
dmcommon.submesh_cell_orientations), so cell closures are ordered identically onboth sides and RT/BDM/N1curl/RTCF/RTCE data transfers exactly instead of picking up sign/permutation
flips.
NotImplementedError,since entity maps are only defined when the two share a distribution; use
Function.assigninstead.MeshHierarchy(redistribute=Trueby default) andrefine_marked_elements/HierarchyBase.adaptredistribute a refined/adapted mesh via
Submeshwhenever it would otherwise leave empty ranks.firedrake/mg/interface.py(prolong/restrict/inject) andfiredrake/mg/utils.py(
transfer_mesh,set_dm_refine_level,set_level) route transfers through the pre-redistributionmesh, then
assignonto the redistributed one.Two supporting changes affect all meshes, not only redistributed ones:
MeshTopology.cell_closuretakes its universal vertex numbering and its quadrilateral cellorientations from two new
cached_propertys,_universal_vertex_numberingand_quadrilateral_cell_orientations, so that a redistributed submesh can inherit its parent's.MeshHierarchyrebuilds the unoverlapped dm from each constructed level rather than refining oneplex repeatedly, so that a level can be redistributed before the next is refined from it.
firedrake/cython/petschdr.pxinow declaresPetscSFBcastBegin/PetscSFBcastEndwith theMPI_Opargument they take. The two newdmcommonfunctions are the only callers of either.Testing
Redistribution round-trips exactly (<= 1e-16) for tri/quad/tet/hex x CG/DG/RT/BDM/N1curl/RTCF/RTCE on
1-3 ranks, including curved (P2) and periodic (DG1) coordinate fields
(
tests/firedrake/submesh/test_submesh_assign.py).tests/firedrake/multigrid/test_redist_mesh.pycovers uniform and adaptive
MeshHierarchyredistribution (2/3/4 ranks);test_submesh_assemble.pycovers the
NotImplementedErrorpaths. All pass at every process count their markers declare.🤖 Generated with Claude Code