16 #include "libmesh/unstructured_mesh.h" 19 StitchedMeshGenerator,
28 params.
addRequiredParam<std::vector<MeshGeneratorName>>(
"inputs",
"The input MeshGenerators.");
29 params.
addParam<
bool>(
"prevent_boundary_ids_overlap",
31 "Whether to re-number boundaries in stitched meshes to prevent merging of " 32 "unrelated boundaries");
34 "merge_boundaries_with_same_name",
36 "If the input meshes have boundaries with the same name (but different IDs), merge them");
38 "subdomain_remapping",
40 "Treat input subdomain names as primary, preserving them and remapping IDs as needed");
42 "verbose_stitching",
false,
"Whether mesh stitching should have verbose output.");
44 "enforce_all_nodes_match_on_boundaries",
46 "Whether to have the stitcher be very picky about the nodes being stitched.");
47 params.
addParam<
bool>(
"merge_boundary_nodes_all_or_nothing",
49 "Whether the stitcher is set to merge all nodes or none.");
51 "Allows multiple mesh files to be stitched together to form a single mesh.");
60 _mesh_ptrs(getMeshes(
"inputs")),
61 _input_names(getParam<
std::vector<MeshGeneratorName>>(
"inputs")),
62 _prevent_boundary_ids_overlap(getParam<bool>(
"prevent_boundary_ids_overlap")),
63 _merge_boundaries_with_same_name(getParam<bool>(
"merge_boundaries_with_same_name"))
68 "Can only stitch one pair of boundary per pair of mesh. We have '" +
70 "' meshes specified (=" + std::to_string(
_input_names.size() - 1) +
72 " pairs of boundaries specified");
77 "' is not of length 2, but of length: " + std::to_string(pair.size()));
80 std::unique_ptr<MeshBase>
86 mooseError(
"StitchMeshGenerator is only implemented for unstructured meshes");
89 std::vector<std::unique_ptr<UnstructuredMesh>> meshes(
_mesh_ptrs.size() - 1);
93 meshes[i - 1] = dynamic_pointer_cast<UnstructuredMesh>(*
_mesh_ptrs[i]);
96 for (MooseIndex(meshes) i = 0; i < meshes.size(); i++)
104 ((i == 0) ?
"" : (
" (stitched with " + std::to_string(i) +
" previous meshes)")),
108 const bool use_binary_search = (
_algorithm ==
"BINARY");
111 if (!
mesh->is_prepared())
112 mesh->prepare_for_use();
113 if (!meshes[i]->is_prepared())
114 meshes[i]->prepare_for_use();
121 const auto & base_mesh_bids =
mesh->get_boundary_info().get_global_boundary_ids();
122 const auto stitched_mesh_bids = meshes[i]->get_boundary_info().get_global_boundary_ids();
125 bool overlap_found =
false;
126 for (
const auto & bid : stitched_mesh_bids)
127 if (base_mesh_bids.count(bid))
128 overlap_found =
true;
132 const auto max_boundary_id =
133 std::max(*base_mesh_bids.rbegin(), *stitched_mesh_bids.rbegin());
135 for (
const auto bid : stitched_mesh_bids)
137 const auto new_bid = max_boundary_id + (new_index++);
138 meshes[i]->get_boundary_info().renumber_id(bid, new_bid);
150 const auto & base_mesh_bids =
mesh->get_boundary_info().get_global_boundary_ids();
151 const auto & other_mesh_bids = meshes[i]->get_boundary_info().get_global_boundary_ids();
154 std::set<boundary_id_type> bd_id_intersection;
155 std::set_intersection(base_mesh_bids.begin(),
156 base_mesh_bids.end(),
157 other_mesh_bids.begin(),
158 other_mesh_bids.end(),
159 std::inserter(bd_id_intersection, bd_id_intersection.begin()));
161 for (
const auto bid : bd_id_intersection)
163 const auto & sideset_name_on_first_mesh =
mesh->get_boundary_info().get_sideset_name(bid);
164 const auto & sideset_name_on_second_mesh =
165 meshes[i]->get_boundary_info().get_sideset_name(bid);
167 if (sideset_name_on_first_mesh != sideset_name_on_second_mesh)
171 " corresponds to different boundary names on the input meshes! On the first " 172 "mesh it corresponds to `",
173 sideset_name_on_first_mesh,
174 "` while on the second mesh it corresponds to `",
175 sideset_name_on_second_mesh,
176 "`. The final mesh will replace boundary `",
177 sideset_name_on_second_mesh,
179 sideset_name_on_first_mesh,
180 "`. To avoid this situation, use the `prevent_boundary_ids_overlap` parameter!");
184 mesh->stitch_meshes(*meshes[i],
187 getParam<Real>(
"stitching_hmin_tolerance_factor"),
189 getParam<bool>(
"verbose_stitching"),
192 getParam<bool>(
"enforce_all_nodes_match_on_boundaries"),
194 getParam<bool>(
"merge_boundary_nodes_all_or_nothing"),
195 getParam<bool>(
"subdomain_remapping"));
201 mesh->unset_is_prepared();
registerMooseObjectRenamed("MooseApp", StitchedMeshGenerator, "06/30/2026 24:00", StitchMeshGenerator)
registerMooseObject("MooseApp", StitchMeshGenerator)
boundary_id_type getBoundaryIdToStitch(const MeshBase &mesh, const std::string &input_mg_name, const BoundaryName &bname) const
Get the boundary id from the name of a boundary to stitch.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
std::unique_ptr< T_DEST, T_DELETER > dynamic_pointer_cast(std::unique_ptr< T_SRC, T_DELETER > &src)
These are reworked from https://stackoverflow.com/a/11003103.
static InputParameters validParams()
const bool _clear_stitched_boundary_ids
Whether or not to clear (remove) the stitched boundary IDs.
static InputParameters validParams()
auto max(const L &left, const R &right)
const bool _merge_boundaries_with_same_name
Whether to merge boundaries if they have the same name but different boundary IDs.
void mooseWarning(Args &&... args) const
const std::string & name() const
Get the name of the class.
const bool _prevent_boundary_ids_overlap
Whether to renumber all boundaries in stitched meshes to prevent accidental merging of sidesets with ...
boundary_id_type BoundaryID
A base class for mesh generators that stitch boundaries together.
Allows multiple mesh files to be "stitched" together to form a single mesh.
std::string stringify(const T &t)
conversion to string
const MooseEnum _algorithm
Type of algorithm used to find matching nodes (binary or exhaustive)
const std::vector< MeshGeneratorName > & _input_names
The mesh generator inputs to read.
StitchMeshGenerator(const InputParameters ¶meters)
std::vector< std::unique_ptr< MeshBase > * > _mesh_ptrs
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
void mergeBoundaryIDsWithSameName(MeshBase &mesh)
Merges the boundary IDs of boundaries that have the same names but different IDs. ...
const std::vector< std::vector< std::string > > _stitch_boundaries_pairs
A transformed version of _stitch_boundaries into a more logical "pairwise" structure.