Skip to content

Commit b972d34

Browse files
authored
Merge pull request #3599 from pmoseley/stitching_all_or_nothing
Improve handling of mesh stitching for non-conforming meshes
2 parents a06162b + f8713a2 commit b972d34

2 files changed

Lines changed: 113 additions & 68 deletions

File tree

include/mesh/unstructured_mesh.h

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,16 @@ class UnstructuredMesh : public MeshBase
180180
* at dealing with slightly misaligned meshes).
181181
* If \p enforce_all_nodes_match_on_boundaries is true, we throw an error if the number of
182182
* nodes on the specified boundaries don't match the number of nodes that were merged.
183-
* This is a helpful error check in some cases.
183+
* This is a helpful error check in some cases. If this is true, it overrides the value of
184+
* \p merge_boundary_nodes_all_or_nothing.
184185
* If \p skip_find_neighbors is true, a faster stitching method is used, where the lists of
185186
* neighbors for each elements are copied as well and patched, without calling the time-consuming
186-
* find_neighbors() function.
187+
* find_neighbors() function. This option is now hard-coded to true.
188+
* If \p merge_boundary_nodes_all_or_nothing is true, instead of throwing an error
189+
* like \p enforce_all_nodes_match_on_boundaries, the meshes are combined anyway but coincident
190+
* nodes are not merged into single nodes. This is useful in cases where you are not sure if the
191+
* boundaries are fully conforming beforehand and you want to handle the non-conforming cases
192+
* differently.
187193
*
188194
* Note that the element IDs for elements in the stitched mesh corresponding to "this" mesh
189195
* will be unchanged. The IDs for elements corresponding to \p other_mesh will be incremented
@@ -192,26 +198,32 @@ class UnstructuredMesh : public MeshBase
192198
* There is no simple a priori relationship between node IDs in "this" mesh
193199
* and other_mesh and node IDs in the stitched mesh because the number of nodes (and hence
194200
* the node IDs) in the stitched mesh depend on how many nodes are stitched.
201+
*
202+
* \returns the count of how many nodes were merged between the two meshes.
203+
* This can be zero in the case of no matching nodes or if
204+
* \p merge_boundary_nodes_all_or_nothing was active and relevant.
195205
*/
196-
void stitch_meshes (const MeshBase & other_mesh,
197-
boundary_id_type this_mesh_boundary,
198-
boundary_id_type other_mesh_boundary,
199-
Real tol=TOLERANCE,
200-
bool clear_stitched_boundary_ids=false,
201-
bool verbose=true,
202-
bool use_binary_search=true,
203-
bool enforce_all_nodes_match_on_boundaries=false);
206+
std::size_t stitch_meshes (const MeshBase & other_mesh,
207+
boundary_id_type this_mesh_boundary,
208+
boundary_id_type other_mesh_boundary,
209+
Real tol=TOLERANCE,
210+
bool clear_stitched_boundary_ids=false,
211+
bool verbose=true,
212+
bool use_binary_search=true,
213+
bool enforce_all_nodes_match_on_boundaries=false,
214+
bool merge_boundary_nodes_all_or_nothing=false);
204215

205216
/**
206217
* Similar to stitch_meshes, except that we stitch two adjacent surfaces within this mesh.
207218
*/
208-
void stitch_surfaces (boundary_id_type boundary_id_1,
209-
boundary_id_type boundary_id_2,
210-
Real tol=TOLERANCE,
211-
bool clear_stitched_boundary_ids=false,
212-
bool verbose=true,
213-
bool use_binary_search=true,
214-
bool enforce_all_nodes_match_on_boundaries=false);
219+
std::size_t stitch_surfaces (boundary_id_type boundary_id_1,
220+
boundary_id_type boundary_id_2,
221+
Real tol=TOLERANCE,
222+
bool clear_stitched_boundary_ids=false,
223+
bool verbose=true,
224+
bool use_binary_search=true,
225+
bool enforce_all_nodes_match_on_boundaries=false,
226+
bool merge_boundary_nodes_all_or_nothing=false);
215227

216228
/**
217229
* Deep copy of nodes and elements from another mesh object (used by
@@ -256,15 +268,16 @@ class UnstructuredMesh : public MeshBase
256268
* Helper function for stitch_meshes and stitch_surfaces
257269
* that does the mesh stitching.
258270
*/
259-
void stitching_helper (const MeshBase * other_mesh,
260-
boundary_id_type boundary_id_1,
261-
boundary_id_type boundary_id_2,
262-
Real tol,
263-
bool clear_stitched_boundary_ids,
264-
bool verbose,
265-
bool use_binary_search,
266-
bool enforce_all_nodes_match_on_boundaries,
267-
bool skip_find_neighbors);
271+
std::size_t stitching_helper (const MeshBase * other_mesh,
272+
boundary_id_type boundary_id_1,
273+
boundary_id_type boundary_id_2,
274+
Real tol,
275+
bool clear_stitched_boundary_ids,
276+
bool verbose,
277+
bool use_binary_search,
278+
bool enforce_all_nodes_match_on_boundaries,
279+
bool skip_find_neighbors,
280+
bool merge_boundary_nodes_all_or_nothing);
268281
};
269282

270283

src/mesh/unstructured_mesh.C

Lines changed: 74 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1721,57 +1721,66 @@ void UnstructuredMesh::all_complete_order ()
17211721
}
17221722

17231723

1724-
void UnstructuredMesh::stitch_meshes (const MeshBase & other_mesh,
1725-
boundary_id_type this_mesh_boundary_id,
1726-
boundary_id_type other_mesh_boundary_id,
1727-
Real tol,
1728-
bool clear_stitched_boundary_ids,
1729-
bool verbose,
1730-
bool use_binary_search,
1731-
bool enforce_all_nodes_match_on_boundaries)
1724+
std::size_t
1725+
UnstructuredMesh::stitch_meshes (const MeshBase & other_mesh,
1726+
boundary_id_type this_mesh_boundary_id,
1727+
boundary_id_type other_mesh_boundary_id,
1728+
Real tol,
1729+
bool clear_stitched_boundary_ids,
1730+
bool verbose,
1731+
bool use_binary_search,
1732+
bool enforce_all_nodes_match_on_boundaries,
1733+
bool merge_boundary_nodes_all_or_nothing)
17321734
{
17331735
LOG_SCOPE("stitch_meshes()", "UnstructuredMesh");
1734-
stitching_helper(&other_mesh,
1735-
this_mesh_boundary_id,
1736-
other_mesh_boundary_id,
1737-
tol,
1738-
clear_stitched_boundary_ids,
1739-
verbose,
1740-
use_binary_search,
1741-
enforce_all_nodes_match_on_boundaries,
1742-
true);
1736+
return stitching_helper(&other_mesh,
1737+
this_mesh_boundary_id,
1738+
other_mesh_boundary_id,
1739+
tol,
1740+
clear_stitched_boundary_ids,
1741+
verbose,
1742+
use_binary_search,
1743+
enforce_all_nodes_match_on_boundaries,
1744+
true,
1745+
merge_boundary_nodes_all_or_nothing);
17431746
}
17441747

17451748

1746-
void UnstructuredMesh::stitch_surfaces (boundary_id_type boundary_id_1,
1747-
boundary_id_type boundary_id_2,
1748-
Real tol,
1749-
bool clear_stitched_boundary_ids,
1750-
bool verbose,
1751-
bool use_binary_search,
1752-
bool enforce_all_nodes_match_on_boundaries)
1749+
std::size_t
1750+
UnstructuredMesh::stitch_surfaces (boundary_id_type boundary_id_1,
1751+
boundary_id_type boundary_id_2,
1752+
Real tol,
1753+
bool clear_stitched_boundary_ids,
1754+
bool verbose,
1755+
bool use_binary_search,
1756+
bool enforce_all_nodes_match_on_boundaries,
1757+
bool merge_boundary_nodes_all_or_nothing)
1758+
17531759
{
1754-
stitching_helper(nullptr,
1755-
boundary_id_1,
1756-
boundary_id_2,
1757-
tol,
1758-
clear_stitched_boundary_ids,
1759-
verbose,
1760-
use_binary_search,
1761-
enforce_all_nodes_match_on_boundaries,
1762-
true);
1760+
return stitching_helper(nullptr,
1761+
boundary_id_1,
1762+
boundary_id_2,
1763+
tol,
1764+
clear_stitched_boundary_ids,
1765+
verbose,
1766+
use_binary_search,
1767+
enforce_all_nodes_match_on_boundaries,
1768+
true,
1769+
merge_boundary_nodes_all_or_nothing);
17631770
}
17641771

17651772

1766-
void UnstructuredMesh::stitching_helper (const MeshBase * other_mesh,
1767-
boundary_id_type this_mesh_boundary_id,
1768-
boundary_id_type other_mesh_boundary_id,
1769-
Real tol,
1770-
bool clear_stitched_boundary_ids,
1771-
bool verbose,
1772-
bool use_binary_search,
1773-
bool enforce_all_nodes_match_on_boundaries,
1774-
bool skip_find_neighbors)
1773+
std::size_t
1774+
UnstructuredMesh::stitching_helper (const MeshBase * other_mesh,
1775+
boundary_id_type this_mesh_boundary_id,
1776+
boundary_id_type other_mesh_boundary_id,
1777+
Real tol,
1778+
bool clear_stitched_boundary_ids,
1779+
bool verbose,
1780+
bool use_binary_search,
1781+
bool enforce_all_nodes_match_on_boundaries,
1782+
bool skip_find_neighbors,
1783+
bool merge_boundary_nodes_all_or_nothing)
17751784
{
17761785
#ifdef DEBUG
17771786
// We rely on neighbor links here
@@ -2109,6 +2118,26 @@ void UnstructuredMesh::stitching_helper (const MeshBase * other_mesh,
21092118
libmesh_error_msg_if((n_matching_nodes != this_mesh_n_nodes) || (n_matching_nodes != other_mesh_n_nodes),
21102119
"Error: We expected the number of nodes to match.");
21112120
}
2121+
2122+
if (merge_boundary_nodes_all_or_nothing)
2123+
{
2124+
std::size_t n_matching_nodes = node_to_node_map.size();
2125+
std::size_t this_mesh_n_nodes = this_boundary_node_ids.size();
2126+
std::size_t other_mesh_n_nodes = other_boundary_node_ids.size();
2127+
if ((n_matching_nodes != this_mesh_n_nodes) || (n_matching_nodes != other_mesh_n_nodes))
2128+
{
2129+
if (verbose)
2130+
{
2131+
libMesh::out << "Skipping node merging in "
2132+
"UnstructuredMesh::stitch_meshes because not "
2133+
"all boundary nodes were matched."
2134+
<< std::endl;
2135+
}
2136+
node_to_node_map.clear();
2137+
other_to_this_node_map.clear();
2138+
node_to_elems_map.clear();
2139+
}
2140+
}
21122141
}
21132142
else
21142143
{
@@ -2395,6 +2424,9 @@ void UnstructuredMesh::stitching_helper (const MeshBase * other_mesh,
23952424
this->get_boundary_info().clear_stitched_boundary_side_ids(
23962425
this_mesh_boundary_id, other_mesh_boundary_id, /*clear_nodeset_data=*/true);
23972426
}
2427+
2428+
// Return the number of nodes which were merged.
2429+
return node_to_node_map.size();
23982430
}
23992431

24002432

0 commit comments

Comments
 (0)