14 #include "libmesh/mesh_tools.h" 15 #include "libmesh/mesh_modification.h" 25 "Mesh generator to perform various improvement / fixing operations on an input mesh");
27 "Name of the mesh generator providing the mesh");
29 params.
addParam<
bool>(
"fix_node_overlap",
false,
"Whether to merge overlapping nodes");
31 "node_overlap_tol", 1e-8,
"Absolute tolerance for merging overlapping nodes");
34 "fix_elements_orientation",
false,
"Whether to flip elements with negative volumes");
36 params.
addParam<
bool>(
"separate_blocks_by_element_types",
38 "Create new blocks if multiple element types are present in a block");
40 params.
addParam<
bool>(
"merge_boundary_ids_with_same_name",
42 "Merge boundaries if they have the same name but different boundary IDs");
49 _input(getMesh(
"input")),
50 _fix_overlapping_nodes(getParam<bool>(
"fix_node_overlap")),
51 _node_overlap_tol(getParam<
Real>(
"node_overlap_tol")),
52 _fix_element_orientation(getParam<bool>(
"fix_elements_orientation")),
53 _elem_type_separation(getParam<bool>(
"separate_blocks_by_element_types")),
54 _boundary_id_merge(getParam<bool>(
"merge_boundary_ids_with_same_name"))
58 mooseError(
"No specific item to fix. Are any of the parameters misspelled?");
61 std::unique_ptr<MeshBase>
64 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
65 mesh->prepare_for_use();
68 if (!
mesh->is_serial())
69 mooseError(
"MeshRepairGenerator requires a serial mesh. The mesh should not be distributed.");
76 MeshTools::Modification::orient_elements(*
mesh);
86 mesh->set_isnt_prepared();
93 unsigned int num_fixed_nodes = 0;
94 auto pl =
mesh->sub_point_locator();
97 std::unordered_set<dof_id_type> nodes_removed;
99 for (
auto & node :
mesh->node_ptr_range())
102 if (nodes_removed.count(node->id()))
106 std::set<const Elem *> elements;
107 (*pl)(*node, elements);
109 for (
auto & elem : elements)
112 for (
auto & elem_node : elem->node_ref_range())
114 if (node->id() == elem_node.id())
122 for (
auto & elem_node : elem->node_ref_range())
124 if (elem_node.id() == node->id())
128 const auto x_node = (*node)(0);
129 const auto x_elem_node = elem_node(0);
130 const auto y_node = (*node)(1);
131 const auto y_elem_node = elem_node(1);
132 const auto z_node = (*node)(2);
133 const auto z_elem_node = elem_node(2);
142 _console <<
"Two overlapping nodes in element " << elem->id() <<
" right by " 143 << elem->vertex_average() <<
".\n They will not be stitched" << std::endl;
149 const_cast<Elem *
>(elem)->set_node(elem->get_node_index(&elem_node), node);
150 nodes_removed.insert(elem_node.id());
153 if (num_fixed_nodes < 10)
154 _console <<
"Stitching nodes " << *node <<
" and " << elem_node
156 else if (num_fixed_nodes == 10)
157 _console <<
"Node stitching will now proceed silently." << std::endl;
163 _console <<
"Number of overlapping nodes which got merged: " << num_fixed_nodes << std::endl;
164 if (
mesh->allow_renumbering())
165 mesh->renumber_nodes_and_elements();
168 mesh->remove_orphaned_nodes();
169 mesh->update_parallel_id_counts();
176 std::set<subdomain_id_type> ids;
177 mesh->subdomain_ids(ids);
179 for (
const auto id : ids)
183 std::set<ElemType> types;
185 for (
auto & elem :
mesh->active_subdomain_elements_ptr_range(
id))
186 types.insert(elem->type());
191 if (types.size() > 1)
194 for (
const auto type : types)
196 auto new_id = next_block_id + i++;
201 for (
auto elem :
mesh->active_subdomain_elements_ptr_range(
id))
202 if (elem->type() ==
type)
203 elem->subdomain_id() = new_id;
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
Function to check whether two variables are equal within an absolute tolerance.
const unsigned int invalid_uint
Mesh generator to perform various improvement / fixing operations on an input mesh.
registerMooseObject("MooseApp", MeshRepairGenerator)
void fixOverlappingNodes(std::unique_ptr< MeshBase > &mesh) const
Removes nodes that overlap.
const bool _boundary_id_merge
Whether to merge boundaries with the same name but different ID.
const bool _elem_type_separation
whether to split subdomains using each element's type
const bool _fix_overlapping_nodes
fixing mesh by deleting overlapping nodes
const std::string & type() const
Get the type of this class.
void separateSubdomainsByElementType(std::unique_ptr< MeshBase > &mesh) const
Separate subdomain by element type because some output format (Exodus) do not support mixed element t...
static InputParameters validParams()
std::string stringify(const T &t)
conversion to string
const bool _fix_element_orientation
whether to flip element orientation such that they no longer have a negative volume ...
std::unique_ptr< MeshBase > & _input
the input mesh
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Real _node_overlap_tol
tolerance for merging overlapping nodes
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
void mergeBoundaryIDsWithSameName(MeshBase &mesh)
Merges the boundary IDs of boundaries that have the same names but different IDs. ...
SubdomainID getNextFreeSubdomainID(MeshBase &input_mesh)
Checks input mesh and returns max(block ID) + 1, which represents a block ID that is not currently in...
MeshGenerators are objects that can modify or add to an existing mesh.
MeshRepairGenerator(const InputParameters ¶meters)
static InputParameters validParams()