Repository navigation
Conversation
_new_uid kept one counter per communicator, so a mesh on COMM_SELF could receive the same ufl_id as a mesh on COMM_WORLD. UFL compares meshes by ufl_id, so a Submesh on COMM_SELF compared equal to its parent, and Function.assign from the parent took the single-mesh path. This gave wrong values and could deadlock a halo exchange. Each communicator now receives, on the first request, an index on which all its ranks agree and that no other communicator on those ranks uses. The uid is the Cantor pairing of that index and the per-communicator counter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A MATIS was preallocated with a global MATPREALLOCATOR, which records only the rows that a rank owns. The local rows of ghost degrees of freedom therefore had no nonzero pattern, so assembly in parallel lost their contributions, and Dirichlet BCs failed on them. The preallocator of a MATIS is now a MATIS whose local matrix is a MATPREALLOCATOR, so the sparsity loop records the local pattern. Local degrees of freedom that no local insertion touches are masked out of the local-to-global maps, as PyOP2 did, so the local matrices have no empty rows. This re-enables test_assemble_matis. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
get_entity_coordinates computes the entity coordinates with a firedrake.par_loop instead of an op2.Kernel. BrokenDirichletBC overrides _nodes, which DirichletBC uses for its node set, so that cellwise BCs take effect. The par_loop in get_primal_indices indexes the marker with the (node, component) shape of par_loop arguments. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A Dat that is passed to a C string kernel without a loop index (for example the Dat of a Constant) has a symbolic size. Loopy needs an integer shape, so take the local maximum of the size. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port FDMPC.condense, which applies the exact Schur complement on the facets with a local KSP that inverts the interior block on each cell. The local KSP is attached to an empty Mat because a pyop3 local kernel can only receive PETSc objects of type Mat. Add a test that uses pc_use_amat with static condensation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port extrude_interior_facet_maps, which the SIPG terms of PoissonFDMPC use. Extruded meshes are DMPlex meshes, so the maps come from the interior vertical and horizontal facet sets instead of the layers. Re-enable the DG and RT cases of test_ipdg_direct_solver. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Split each interior_facet integral over an extruded mesh into its interior_facet_vert and interior_facet_horiz parts before calling TSFC. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dat.from_components stores each Dat in its root component, in the layout of the axes, so that the owned entries of all components come first. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The interior facets of an extruded mesh are the union of its vertical and horizontal interior facets, with one component for each. The DoF maps and the local facet numbers on this set are built from those of the two components. The local facet numbers of horizontal facets follow the vertical facets, as in the facet numbering of a tensor-product cell. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Extruded meshes now support dS and interior_facets, so FDM reads the interior facet maps of every mesh directly and no longer assembles dS_h + dS_v. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pbrubeck
force-pushed
the
pbrubeck/bddc-pyop3
branch
3 times, most recently
from
October 26, 2026 10:10
4ec2436 to
294b666
Compare
This branch has not been deployed
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.
Stacked on #5541; review only the last four commits.
Summary
dSandmesh.interior_facetsnow work on extruded meshes, so FDM no longer needsextrude_interior_facet_maps.Form compilation splits
dSbefore TSFC:On an extruded mesh, the interior facets are one entity set with one component per stratum:
op3.Dat.from_componentsis new. It builds a Dat on a set with several components from one Dat per component, in the layout of the axes. Owned entries of all components come first, so[:nfacets]still selects the owned facets.FDM reads the interior facet maps of every mesh in the same way:
Evidence
assemble(Constant(1)*dS(domain=extruded_mesh))raisesValueError: interior_facet integral cannot be used with a TensorProductCell.mesh.interior_facetsraisesTypeErroron extruded meshes.After:
test_interior_facet_dS_extrgets an interior facet area of 3.0 on the unit cube with 2x2x2 cells.test_interior_facet_maps_extrchecks that, on every rank, the node list and the local facet numbers describe the same owned facets, and that the ranks together own the 10 interior facets once. Both pass at 1 and 3 ranks. The maps test fails at 3 ranks if the subset Dats are concatenated instead of laid out by pyop3.tests/pyop3/expr/tensor/test_dat.py::test_from_componentschecks that owned entries of all components are stored before the ghost entries.tests/firedrake/extrusion/and the facet regression tests (test_facet_*.py,test_facets.py,test_interior_facets.py,test_mixed_interior_facets.py): 586 passed at 1 rank, 54 passed at 3 ranks, 0 failed.test_fdm.py::test_ipdg_direct_solverpasses forcg/dg/rt-Boxanddg/rt-Rectangle.Merge Danger
Door: two-way
Blast Radius: mesh
_entity_axes_by_namebuilds every named entity set, so a regression would show up in facet assembly on all meshes. On extruded meshes,V.interior_facet_node_listreturns only owned rows, while on other meshes it also returns ghost rows.This PR was prepared with Claude Code.
🤖 Generated with Claude Code