Skip to content

Conversation

pbehne
Copy link
Contributor

@pbehne pbehne commented Jul 17, 2025

Pull Request: Sliding Boundary Constraint Refinement and Dimensional Generalization

Summary

This pull request implements sliding external and subdomain boundary node constraints in the VariationalMeshSmoother
In addition to expanding test coverage to test sliding boundary nodes, 1D and 3D test cases were added to the unit test suite.

Highlights

  • Constraint Framework Refactor

    • Introduced PointConstraint, LineConstraint, and PlaneConstraint classes to represent fixed nodes, nodes constrained to a line, and nodes constrained to a plane
    • Implemented a unified intersect() interface for combining constraints using std::variant
    • Added robust geometric logic for line-line, plane-line, and plane-plane intersections
    • Fallback to PointConstraint if constraints fail to intersect cleanly
  • Sliding Boundary Enhancements

    • Implemented sliding boundary node constraints: previously, boundary and subdomain boundary nodes were fully fixed and not allowed to slide
    • Nodes on external boundaries internal subdomain boundaries now slide along planes and lines unless constrained by geometry
  • Expanded Tests and Validation

    • Added new smoother test cases in 1D and 3D
    • Replaced DistortSquare with DistortHypercube, supporting 1D, 2D, and 3D skewing
    • Boundary nodes are now distorted within the faces and edges they belong to (while preserving corner vertices)
    • Increased complexity of subdomain boundary test to cover more complex cases such a an element having neighbors of multiply different subdomain ids

References

Visualization of testVariationalHexMultipleSubdomains Test

The distorted mesh is on the left, smoothed mesh is on the right.
image

pbehne added 23 commits July 17, 2025 13:09
…re considered for sliding boundary constraints. This helps with adjacent corners nodes in triangular elements.
…ain tests to account for barely-moved subdomain boundary nodes that coincide with the mesh boundary.
…ks better, but both constaints should be conmbined for strict enforcement.
Implemented structs to represent Point, Line, and Plane constraints and
logic to combine (intersect) them. This is more robust than the previous
version and gives the correct constraints for nodes that are both
subdomain boundary nodes and external boundary nodes.
Ref libMesh#4082
Replaced DistortSquare class with the DistortHypercube class, which generalizes dimension and distorts boundary nodes within boundaries instead of leaving them unchanged. The helper also checks all applicable node dimensions instead of receiving the dimension to check as a parameter.

Renamed the `center_distortion_is` helper function to `distortion_is` and updated to check sliding boundary nodes for distortion.
Instead of looking for the boundary between sub_id2 and sub_id2, we now
look for the boundary between sub_id1 and "not sub_id1". This better
handles cases where multiple faces of an element have neighbors of
multiple different subdomain ids.
Copy link
Member

@roystgnr roystgnr left a comment

Choose a reason for hiding this comment

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

There's surprisingly little for me to complain about, for such a large PR.

@moosebuild
Copy link

moosebuild commented Jul 18, 2025

Job Coverage, step Generate coverage on f8c37d4 wanted to post the following:

Coverage

f5e204 #4216 f8c37d
Total Total +/- New
Rate 64.33% 64.42% +0.09% 87.65%
Hits 75207 75559 +352 369
Misses 41701 41725 +24 52

Diff coverage report

Full coverage report

Warnings

  • New new line coverage rate 87.65% is less than the suggested 90.0%

This comment will be updated on new commits.

@roystgnr
Copy link
Member

From Slack, for public reference:

"Okay, just pushed the polymorphic approach. Let me know which one you prefer and we'll stick with that."

"I think I like the std::variant version better. Sorry to make you go to so much work! I'd be okay with either version."

"Yes, the polymorphic feels a bit more cluttered, doesn’t it? No worries, I was interested in how it would turn out"

I think my only remaining real complaint is that, even if we end up relying on exceptions here, at a minimum we need to disable the tests relying on them until the --disable-exceptions CI passes.

Copy link
Member

@roystgnr roystgnr left a comment

Choose a reason for hiding this comment

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

I'm thrilled with this now except for a couple of the whitespace changes; @pbehne is going to rewrite history now, and has sworn he won't edit anything else but whitespace in the process.

@pbehne pbehne force-pushed the variational_smoother_sliding_boundary_nodes branch from d2b4489 to 57c7c4e Compare July 23, 2025 21:29
Copy link
Member

@jwpeterson jwpeterson left a comment

Choose a reason for hiding this comment

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

Looks good to me although I can't really comment on the technical details. I think some of the new std::variant and std::visit C++17 code could potentially be commented more. I know that it's possible to look up how these things work, but (to my knowledge) we don't use this anywhere else in the library so it would be handy to have a nearby comment explaining how these "modern" C++ concepts help to implement the overall design.

@moosebuild
Copy link

Job Min gcc on f8c37d4 : invalidated by @jwpeterson

Retry to see if "failed to get checksum" error is resolved automatically

@jwpeterson jwpeterson requested a review from roystgnr July 25, 2025 13:05
@roystgnr roystgnr merged commit 079a331 into libMesh:devel Jul 28, 2025
22 checks passed
@roystgnr roystgnr deleted the variational_smoother_sliding_boundary_nodes branch July 28, 2025 20:54
@jwpeterson
Copy link
Member

FYI @pbehne this PR seems to have broken the --disable-deprecated build (see here, for example: https://civet.inl.gov/branch/14145/). The error message is:

../src/systems/variational_smoother_system.C: In member function 'void libMesh::VariationalSmootherSystem::prepare_for_smoothing()':
../src/systems/variational_smoother_system.C:158:37: error: no matching function for call to 'libMesh::Tri3::set_node(int)'
               target_elem.set_node(0) = &node_0;
                                     ^
In file included from ../src/systems/variational_smoother_system.C:20:
./include/libmesh/elem.h:2571:6: note: candidate: 'virtual void libMesh::Elem::set_node(unsigned int, libMesh::Node*)'
 void Elem::set_node (const unsigned int i,
      ^~~~
./include/libmesh/elem.h:2571:6: note:   candidate expects 2 arguments, 1 provided
../src/systems/variational_smoother_system.C:159:37: error: no matching function for call to 'libMesh::Tri3::set_node(int)'
               target_elem.set_node(1) = &node_1;
                                     ^
In file included from ../src/systems/variational_smoother_system.C:20:
./include/libmesh/elem.h:2571:6: note: candidate: 'virtual void libMesh::Elem::set_node(unsigned int, libMesh::Node*)'
 void Elem::set_node (const unsigned int i,
      ^~~~
./include/libmesh/elem.h:2571:6: note:   candidate expects 2 arguments, 1 provided
../src/systems/variational_smoother_system.C:160:37: error: no matching function for call to 'libMesh::Tri3::set_node(int)'
               target_elem.set_node(2) = &node_2;
                                     ^
In file included from ../src/systems/variational_smoother_system.C:20:
./include/libmesh/elem.h:2571:6: note: candidate: 'virtual void libMesh::Elem::set_node(unsigned int, libMesh::Node*)'
 void Elem::set_node (const unsigned int i,
      ^~~~
./include/libmesh/elem.h:2571:6: note:   candidate expects 2 arguments, 1 provided

so the fix should be simple, just use the non-deprecated Elem::set_node() API instead.

@pbehne
Copy link
Contributor Author

pbehne commented Jul 30, 2025

Thanks for the heads up, I'll add the fix to #4218!

@pbehne
Copy link
Contributor Author

pbehne commented Jul 30, 2025

FYI, only the deprecated version shows up in doxygen. I had to go look at elem.h to see the non-deprecated version.

@jwpeterson
Copy link
Member

FYI, only the deprecated version shows up in doxygen. I had to go look at elem.h to see the non-deprecated version.

OK, that's interesting... I guess Doxygen is somehow seeing the "pre-processed" version of the source (and the defines are somehow set such that it doesn't generate docs for the non-deprecated version)? Maybe that's a normal Doxygen thing, I don't know.

@pbehne
Copy link
Contributor Author

pbehne commented Jul 30, 2025

Yeah, I figured I'd mention it since I recall @roystgnr mentioning that he and you typically just use the header files themselves for documentation. As someone less familiar with the library, I prefer doxygen so I don't have to dig through parent headers to see what a given class does and doesn't inherit.

@roystgnr
Copy link
Member

I think the problem is that we only update the libMesh Doxygen manuallly, by which I mean "almost never", by which I mean "Oh my God the files still have copyright 2002-2018 headers". The libMesh Doxygen on the MOOSE site gets autoupdated, which I guess I thought was good enough ... but it doesn't matter if the MOOSE copy marks something as deprecated if that's not the copy everybody is reading.

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.

4 participants