Skip to content

Macnider/interior boundary domains#1536

Open
bmacnider wants to merge 8 commits intodevelopfrom
macnider/interior_boundary_domains
Open

Macnider/interior boundary domains#1536
bmacnider wants to merge 8 commits intodevelopfrom
macnider/interior_boundary_domains

Conversation

@bmacnider
Copy link
Contributor

Adding the ability to create a domain out of an interior boundary, as the previous method to create a domain of boundary elements excluded all interior elements.

Copy link
Collaborator

@tupek2 tupek2 left a comment

Choose a reason for hiding this comment

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

Please double check some slight additional logic. Make sure the exterior and interior areas are as expected. Is this run in parallel?

if (!mesh.GetFaceInformation(f).IsInterior()) {
switch (geom) {
case mfem::Geometry::SEGMENT:
edge_id++;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why are we incrementing the counter on exterior edges that we are not included in the interior edges set?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's because in the case that you have both an exterior and an interior boundary domain, and you don't increment values for the one you are excluding, you end up with domains of the same type that have repeated ID values in them. If you then try to do a domain operation with these two, like a union or difference, the repeated values cause an error. The incrementing on the edges we are skipping over makes sure that the two boundary domains have unique ID values.

Copy link
Member

Choose a reason for hiding this comment

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

Referring to my comment above, I think that the Type should be different for interior and exterior faces, which resolves the problem of handling set operations (by forbidding them). If we agree on that, then the old logic should go back in: you won't count the exterior edges/faces in the internal boundary sets, and vice versa.

@tupek2 tupek2 self-requested a review February 18, 2026 21:43
{
assert(mesh.SpaceDimension() == d);

Domain output{mesh, d - 1, Domain::Type::BoundaryElements};
Copy link
Member

Choose a reason for hiding this comment

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

Should the type be Domain::Type::InteriorFaces? I think that's the intent of that type, to differentiate between boundary and inter-element faces. @lihanyu97, you've worked on this more recently, can you confirm? My thinking is that Domain is meant for integrating over. We sort the domains into types of like elements so that Functional objects can iterate over all the elements and repeat the same calculation efficiently, not have to test each element to choose the right logic and data layout sizing.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, Domain::Type::BoundaryElements only refer to those faces/edges on the boundary of the global domain. Domain::Type::InteriorFaces refer to those faces/edges in the interior of the domain. So if a face/edge is in the interior of the global domain but on the local processor boundary, it is also considered a InteriorFace

if (!mesh.GetFaceInformation(f).IsInterior()) {
switch (geom) {
case mfem::Geometry::SEGMENT:
edge_id++;
Copy link
Member

Choose a reason for hiding this comment

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

Referring to my comment above, I think that the Type should be different for interior and exterior faces, which resolves the problem of handling set operations (by forbidding them). If we agree on that, then the old logic should go back in: you won't count the exterior edges/faces in the internal boundary sets, and vice versa.

#include "smith/smith_config.hpp"
#include "smith/mesh_utils/mesh_utils.hpp"

#include "smith/smith_config.hpp"
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
#include "smith/smith_config.hpp"

Copy link
Member

Choose a reason for hiding this comment

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

Good catch.

// faces that satisfy the predicate are added to the domain
for (int f = 0; f < mesh.GetNumFaces(); f++) {
auto geom = mesh.GetFaceGeometry(f);

Copy link
Contributor

@lihanyu97 lihanyu97 Feb 25, 2026

Choose a reason for hiding this comment

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

Calling the predicate to determine whether to add a interior face or not can be done here. Instead of calling GetBdrAttribute, you can directly point to the face/edge and call GetElementAttribute, assuming that in cubit you have a unique attribute assigned to the set of interior faces that you want to integrate on.

if one of your interior face is on the processor boundary, then it's going to get counted twice by two different processors and your QoI is integrated twice on that interior face. That's why I implemented insert_shared_interior_face_list which should always be invoked and present if you have a domain of interior faces. I have configured functional and functional qoi accordingly such that the integration is scaled by 0.5 so that when they get integrated twice, the global sum equal to one. This behavior is not related to whether you are on H1 or L2 spaces.

Finally, function makes element restriction to the domain you pass in. If geometry_dim + 1 = space_dim, indicating it's a face integral, ElementRestriction will call GetFaceDofs. The old version of the function is not deleted yet so it might confuse you. We are now calling the newer version here:

axom::Array<DoF, 2, smith::detail::host_memory_space> GetFaceDofs(const smith::fes_t* fes,

I implemented the DG part to grab DoFs on both side of the face. But you can see the search is handled differently. If the space is H1 or HCurl (line 607), it directly calls the native mfem function and you don't get dofs on both side.

///////////////////////////////////////////////////////////////////////////////////////

template <int d>
static Domain domain_of_boundary_elems(const mesh_t& mesh,
Copy link
Contributor

Choose a reason for hiding this comment

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

I would leave this method unchanged.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants