Skip to content

Conversation

jorgensd
Copy link
Member

@jorgensd jorgensd commented Sep 3, 2025

New features

  • Introduces ridge integrals (ufl.dr) (tdim - 2) (for rank 0, 1 and 2-tensors)
  • Unifies assembly routines in assemble_vector for all exterior entity integrals.
  • Adds assemble_matrix and apply_lifting for vertex integrals

Context

Any one-sided sub entity integral boils down to getting the correct (cell, local_entity_index), and assemble over these.
The lower level assembly routines (assemble_exterior_facet, assemble_vertex) does not really differ in this respect. It is only due to the fact that facets might require permutations that codes were not identical.
This became crystal clear when introducing ridge integrals.

Consequences

  • The assemble_vertex routines recently introduced are removed in favor of an assemble_exterior_facet function, now renamed as assemble_exterior_entities. This is also used for ridge integrals.

Bugs encountered

  • There is a subtle bug in the coefficient allocation of vertex integrals, where the double amount of memory is allocated. Adjusted packing to divide by two for all integral types but cells.

Future work

Mixed dimensional support for codim-2.
For this to work, a few things have to be introduced:

  • require_ridge_permutation has to be introduced in FFCx
  • Computing ridge-permutation has to be a member of DOLFINx (similar to compute facet permutations)

@jorgensd jorgensd requested a review from jpdean September 3, 2025 10:32
Copy link
Contributor

@schnellerhase schnellerhase left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice code duplication removal!

@michalhabera
Copy link
Contributor

The unification reads really well.

One point to consider, for future design, given the increase in type of integral we are seeing:
Vertex integrals are effectively defined by dimension (vertex: dim=0), while all other come with a codimension (cell: codim=0, facets: codim=-1, ridge: codim=-2). The root of this is also in UFL, and surely we want to keep it for user convenience, but we should try to separate the logic early enough, strip all data to a common pattern for both dim/codim and follow unified codepath onwards. I think your PR is the step in right direction as it moves all integral assemble routines to the codimension format. However, we should also avoid IntegralType with duplicate values as much as possible: in 2D ridge integral in == vertex integral.

@jorgensd
Copy link
Member Author

jorgensd commented Sep 3, 2025

The unification reads really well.

One point to consider, for future design, given the increase in type of integral we are seeing: Vertex integrals are effectively defined by dimension (vertex: dim=0), while all other come with a codimension (cell: codim=0, facets: codim=-1, ridge: codim=-2). The root of this is also in UFL, and surely we want to keep it for user convenience, but we should try to separate the logic early enough, strip all data to a common pattern for both dim/codim and follow unified codepath onwards. I think your PR is the step in right direction as it moves all integral assemble routines to the codimension format. However, we should also avoid IntegralType with duplicate values as much as possible: in 2D ridge integral in == vertex integral.

I think if we ever introduce "peak" integrals, they would effectively replace the vertex integrals, as we should always go down the "co-dimension" route (for the sake of mixed assembly support).

@schnellerhase
Copy link
Contributor

schnellerhase commented Sep 3, 2025

Once we have the ridge integral which aligns with vertex integral for tdim=2, then for tdim=3 peak=vertex so we can just rename vertex->peak after introducing ridge.

@jorgensd jorgensd marked this pull request as ready for review September 3, 2025 13:34
@jorgensd jorgensd added enhancement New feature or request housekeeping Tidying and style improvements labels Sep 3, 2025
@jorgensd jorgensd added this to the 0.10.0 milestone Sep 3, 2025
@jorgensd jorgensd changed the title Unification of one-sided sub-entity integrals Unification of one-sided sub-entity integrals + ridge integrals Sep 3, 2025
@garth-wells
Copy link
Member

@garth-wells Renaming exterior_facet to facet cascades deep into FFCx, and should be handled in a separate PR, as there are tons of bad use-cases of ufl strings in there. Especially if we now want to remove the enum altogether, I think we leave it in this PR and change in soon.

Something has gone very badly wrong in the DOLFINX design if this is the case. It should be relatively easy to rename an enum, or change the enum to a pair of integers, in DOLFINx without changing UFCx or FFCx. What specifically causes a 'cascade' into FFCx?

@jorgensd
Copy link
Member Author

@garth-wells Renaming exterior_facet to facet cascades deep into FFCx, and should be handled in a separate PR, as there are tons of bad use-cases of ufl strings in there. Especially if we now want to remove the enum altogether, I think we leave it in this PR and change in soon.

Something has gone very badly wrong in the DOLFINX design if this is the case. It should be relatively easy to rename an enum, or change the enum to a pair of integers, in DOLFINx without changing UFCx or FFCx. What specifically causes a 'cascade' into FFCx?

This is being handled separately in:
FEniCS/ffcx#787

@garth-wells
Copy link
Member

@garth-wells Renaming exterior_facet to facet cascades deep into FFCx, and should be handled in a separate PR, as there are tons of bad use-cases of ufl strings in there. Especially if we now want to remove the enum altogether, I think we leave it in this PR and change in soon.

Something has gone very badly wrong in the DOLFINX design if this is the case. It should be relatively easy to rename an enum, or change the enum to a pair of integers, in DOLFINx without changing UFCx or FFCx. What specifically causes a 'cascade' into FFCx?

This is being handled separately in: FEniCS/ffcx#787

But what's the issue? I can't see it. If we have such tight coupling between DOLFINx and FFCx/UFCx there is a design mistake that needs to be fixed.

@jorgensd
Copy link
Member Author

jorgensd commented Sep 10, 2025

@garth-wells Renaming exterior_facet to facet cascades deep into FFCx, and should be handled in a separate PR, as there are tons of bad use-cases of ufl strings in there. Especially if we now want to remove the enum altogether, I think we leave it in this PR and change in soon.

Something has gone very badly wrong in the DOLFINX design if this is the case. It should be relatively easy to rename an enum, or change the enum to a pair of integers, in DOLFINx without changing UFCx or FFCx. What specifically causes a 'cascade' into FFCx?

This is being handled separately in: FEniCS/ffcx#787

But what's the issue? I can't see it. If we have such tight coupling between DOLFINx and FFCx/UFCx there is a design mistake that needs to be fixed.

Currently in DOLFINx we look things up by strings, and assume that they match with things in FFCx and UFL.
This is bad design and something I have taken care of in:

Copy link
Contributor

@michalhabera michalhabera left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am happy with this PR, I only see minor potential for naming improvement, as after the PR we will have:

  1. assemble_entities
    assembles over provided entities (regardless of their dim/codim) restricted to 0th adjacent cell, could as well be called assemble_entities_cell0?.

And two more specialized cases:

  1. assemble_cells
    assembles over cells restricted to 0th (but the only) adjacent cell (itself),
  2. assemble_interior_facets
    assembles over facets (codim=1) with restriction being based on exactly first two adjacent cells.

If we'd like to unify the special cases, with some work we can use assemble_entities_cell0 to handle assemble_cells -- the only complication now I think is different data format of entities array, and also generalize assemble_interior_facets to assemble_entities_cell0cell1. This proposed naming is very explicit in what the function does.

This PR does not add any complexity, it actually exposes the shortcomings of the current design where the assumptions on: 1. what do we integrate over and 2. what adjacent entities is it restricted to, are simply buried in the code, not clear from the API.

@cdaversin
Copy link

Glad to see the ridge integrals are coming their way! The unification makes real sense to me. In addition to the significant duplicated code removal, the "re-naming" of the assembly functions with entities instead of facets makes the code more generic and less confusing when working with various dimension / co-dimensions.

I agree with @michalhabera 's point on moving assembly routines to "the codimension format". I think @jorgensd 's PR#3919 with a dedicated class IntegralType is a smart way to define the integral types from their codimension and number of adjacent cells. This class is simple/light but flexible to include future type of integrals (some which can be difficult to name / define as a string)

This is a big step towards codimension > 1 :)

@jorgensd jorgensd dismissed garth-wells’s stale review September 26, 2025 08:40

All questions regarding this change has been addressed.
A rewrite of IntegralType should be addressed in another PR

@jorgensd jorgensd added this pull request to the merge queue Oct 2, 2025
Merged via the queue into main with commit 547df9f Oct 2, 2025
20 checks passed
@jorgensd jorgensd deleted the dokken/ridge-integrals branch October 2, 2025 07:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request housekeeping Tidying and style improvements

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants