14 #include "libmesh/mesh_modification.h" 26 params.
addRequiredParam<MeshGeneratorName>(
"input",
"The mesh we want to modify");
30 "Elements with these boundary ID(s)/name(s) will be given the new boundary information " 31 "specified in 'new_boundary'");
34 "The new boundary ID(s)/name(s) to be given by the boundary elements defined in " 38 "Changes the boundary IDs and/or boundary names for a given set of " 39 "boundaries defined by either boundary ID or boundary name. The " 40 "changes are independent of ordering. The merging of boundaries is supported.");
48 _old_boundary = getParam<std::vector<BoundaryName>>(
"old_boundary");
50 _new_boundary = getParam<std::vector<BoundaryName>>(
"new_boundary");
53 paramError(
"new_boundary",
"Must be the same length as 'old_boundary'");
56 std::unique_ptr<MeshBase>
59 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
61 auto & boundary_info =
mesh->get_boundary_info();
65 std::set<BoundaryID> boundary_ids = boundary_info.get_boundary_ids();
68 mesh->comm().set_union(boundary_ids);
72 auto get_unused_boundary_id = [
this, &boundary_ids, &boundary_info]()
76 if (!boundary_ids.count(
id) && !boundary_info.get_sideset_name_map().count(
id) &&
77 !boundary_info.get_nodeset_name_map().count(
id))
79 boundary_ids.insert(
id);
89 const auto is_boundary_id = [](
const BoundaryName & boundary_name)
96 std::vector<std::string> old_boundary_names(num_boundaries);
97 std::stringstream missing_boundary;
98 for (
const auto i :
make_range(num_boundaries))
104 old_boundary_ids[i] = id;
107 if (!boundary_ids.count(
id))
108 missing_boundary <<
name <<
" ";
112 if (is_boundary_id(
name))
114 old_boundary_names[i] = boundary_info.get_sideset_name(
id);
115 if (old_boundary_names[i].empty())
116 old_boundary_names[i] = boundary_info.get_nodeset_name(
id);
120 old_boundary_names[i] =
name;
122 if (missing_boundary.str().size())
124 "The following boundaries were requested to be renamed, but do not exist: ",
125 missing_boundary.str());
129 std::map<BoundaryID, std::string> new_names;
130 for (
const auto i :
make_range(num_boundaries))
135 if (is_boundary_id(
name))
138 new_boundary_ids[i] = id;
142 boundary_ids.insert(
id);
145 if (old_boundary_names[i].size())
148 if (old_boundary_names[i] == std::to_string(old_boundary_ids[i]))
149 new_names[id] = std::to_string(new_boundary_ids[i]);
151 new_names[id] = old_boundary_names[i];
159 bool name_already_exists =
false;
163 for (
const auto map : {&boundary_info.set_sideset_name_map(),
164 &boundary_info.set_nodeset_name_map(),
166 for (
const auto & id_name_pair : *map)
167 if (!name_already_exists && id_name_pair.second ==
name)
169 new_boundary_ids[i] = id_name_pair.first;
170 new_names[id_name_pair.first] =
name;
171 name_already_exists =
true;
175 if (!name_already_exists)
177 new_boundary_ids[i] = old_boundary_ids[i];
178 new_names[new_boundary_ids[i]] =
name;
194 auto temp_new_boundary_ids = new_boundary_ids;
195 std::vector<std::pair<BoundaryID, BoundaryID>> temp_change_ids;
197 for (
const auto new_i :
make_range(num_boundaries))
202 for (
const auto old_i :
make_range(new_i + 1, num_boundaries))
203 if (new_boundary_ids[new_i] == old_boundary_ids[old_i])
205 const auto temp_id = get_unused_boundary_id();
206 temp_change_ids.emplace_back(temp_id, new_boundary_ids[new_i]);
207 temp_new_boundary_ids[new_i] = temp_id;
213 for (
const auto i :
make_range(num_boundaries))
214 MeshTools::Modification::change_boundary_id(
215 *
mesh, old_boundary_ids[i], temp_new_boundary_ids[i]);
218 for (
const auto & pair : temp_change_ids)
219 MeshTools::Modification::change_boundary_id(*
mesh, pair.first, pair.second);
222 for (
const auto i :
make_range(num_boundaries))
224 if (boundary_info.get_sideset_name_map().count(old_boundary_ids[i]))
225 boundary_info.set_sideset_name_map().erase(old_boundary_ids[i]);
226 if (boundary_info.get_nodeset_name_map().count(old_boundary_ids[i]))
227 boundary_info.set_nodeset_name_map().erase(old_boundary_ids[i]);
231 for (
const auto & pair : new_names)
233 boundary_info.sideset_name(pair.first) = pair.second;
234 boundary_info.nodeset_name(pair.first) = pair.second;
237 mesh->set_isnt_prepared();
std::unique_ptr< MeshBase > & _input
MeshGenerator for re-numbering or re-naming boundaries.
const BoundaryID INVALID_BOUNDARY_ID
std::vector< BoundaryName > _old_boundary
The old boundaries.
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.
std::vector< BoundaryName > _new_boundary
The new boundaries.
registerMooseObject("MooseApp", RenameBoundaryGenerator)
virtual const std::string & name() const
Get the name of the class.
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
Gets the boundary ID associated with the given BoundaryName.
boundary_id_type BoundaryID
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 ...
static InputParameters validParams()
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
static InputParameters validParams()
IntRange< T > make_range(T beg, T end)
RenameBoundaryGenerator(const InputParameters ¶meters)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
bool isDigits(const std::string &str)
Courtesy https://stackoverflow.com/a/8889045 and https://en.cppreference.com/w/cpp/string/byte/isdigi...
MeshGenerators are objects that can modify or add to an existing mesh.