MeshGenerator for Breaking Mesh Along Embedded Side Sets #31296
-
|
Dear MOOSE Team, I’m currently working on developing a To implement this, I’ve been following the logic used in
However, I’m encountering a couple of issues and would appreciate your guidance: Question 1: In my case, subdomain IDs are not applicable. My idea was to identify the positive and negative sides of the interface using the normal vector of the embedded side set. Specifically, for each element connected to the embedded side set, we can compute the face normal using the cross product of two in-plane vectors: where Here’s the issue: it seems that libMesh reorders the nodes of a face shared between two elements in a way that the computed normal vector is always inward-facing relative to the element. Is this understanding correct? If so, is there a way to obtain a consistent face normal that is independent of node ordering? Alternatively, is there a recommended approach in libMesh for determining which side of an arbitrary interface an element lies on? Question 2: I didn’t find an existing method in Best regards, |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 4 replies
-
|
Hello That mesh generator is a great idea. It would fit well into MOOSE
The normal vector for a sideset is always facing outwards (from primary to secondary side). This is the vector you want to use to distinguish the two sides of the mesh wrt to the sideset. You get that from the (elem, side, bid) tuple.
To find these nodes, you look at the nodeToElem map in mooseMesh (or build one if you only have a MeshBase). These nodes will have at least one of the elements in the nodeToElemMap that has no side that is part of the sideset |
Beta Was this translation helpful? Give feedback.
-
|
Thank you, @GiudGiud, for your response. I forgot to mention in my initial post that I’m looking for a general solution that works for both TET4 and HEX8 elements. With TET4 elements—unlike HEX8—there can be many elements on both sides of the sideset that only share a single node or edge with the sideset, rather than a full face. These elements are part of the sideset and still appear in my I’ve managed to solve the first issue related to normal vector calculation, particularly for elements that do not have a full face on the sideset. However, I still haven’t found a good solution for the second issue. A third issue I’ve encountered involves elements located at the intersection of two sidesets (e.g., two intersecting fractures). These elements may be considered primary for one sideset and secondary for the other, which leads to a contradiction that needs to be resolved. I’m skipping this issue for now, but I may return to it and reach out again if I can't figure it out. Best regards, |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
|
Dear @GiudGiud, Following your suggestion, I tested two setups:
In this setup, the user assigns a single ID to all embedded sidesets that need to be split, and the mesh is processed by one generator. The sideset can include multiple surfaces, branches, and intersections. A typical application is in Discrete Fracture Network (DFN) modeling, where numerous randomly distributed fractures intersect. The user assigns the same physical name (ID) to all fractures. An example input looks like this: Pros: Simplifies the mesh definition when many sidesets need to be split. Cons: Managing intersections is challenging. Each intersection point requires three copies of the node. Since all sideset faces share the same ID, it is difficult to implement a general and robust solution that works across different element types and shapes. A potential solution (not yet tested) is to internally group faces based on their normal vectors, essentially creating temporary sideset IDs and then iterating over these groups to split them individually (similar to Setup 2 below).
In this configuration, i used a single generator to split the mesh. The sidesets are listed in a vector, each with a unique ID. Each sideset represents a flat or curved surface without branches or intersections. I tested this setup, and it works well: both intersecting and terminal nodes are handled correctly. Because each embedded surface has its own ID, it is straightforward to identify intersection points and duplicate them properly by iterating over the sidesets and copying both the original and newly generated nodes. Pros: Easy to implement. Full control over node duplication and renumbering, especially at intersections, since everything is handled within a single generator. Cons: For large models, the vector list of sidesets and interfaces can become very long. For now, I will continue with Setup 2, although it would also be useful to have Setup 1 since it is more general. However, I am encountering a new issue! After splitting the mesh, if I use any other MeshGenerator that calls prepared_for_use() (e.g., in LowerDBlockFromSidesetGenerator), the element-neighbor information is deleted, and the cohesive interface no longer works. Best regards, |
Beta Was this translation helpful? Give feedback.

dont worry about this. With input file includes, you can put this mesh generator in a separate file.
I think this is the same problem as the BreakMeshByBlockGenerator.
There is some special logic in MooseMesh to prevent that. Look for calls to
has_bbmgwhich is checking for the use of that mesh generator