14 #include "libmesh/mesh_modification.h" 26 params.
addRequiredParam<MeshGeneratorName>(
"input",
"The mesh we want to modify");
29 "Elements with these boundary ID(s) will be given the new boundary ID(s) and/or name(s). You " 30 "must supply either 'old_boundary_id' or 'old_boundary_name'.",
31 "Use 'old_boundary' instead of 'old_boundary_id'.");
34 "Elements with these boundary name(s) will be given the new boundary ID(s) and/or name(s). " 35 "You must supply either 'old_boundary_id' or 'old_boundary_name'.",
36 "Use 'old_boundary' instead of 'old_boundary_name'");
39 "The new boundary ID(s) for the elements defined by " 40 "'old_boundary_id' or 'old_boundary_name'.",
41 "Use 'new_boundary' instead of 'new_boundary_id'.");
44 "The new boundary name(s) for the elements defined by " 45 "'old_boundary_id' or 'old_boundary_name'. If 'new_boundary_id' is not provided and a " 46 "boundary with the given name does not exist, a new boundary ID will be created.",
47 "Use 'new_boundary' instead of 'new_boundary_name'.");
49 params.
addParam<std::vector<BoundaryName>>(
51 "Elements with these boundary ID(s)/name(s) will be given the new boundary information " 52 "specified in 'new_boundary'");
53 params.
addParam<std::vector<BoundaryName>>(
55 "The new boundary ID(s)/name(s) to be given by the boundary elements defined in " 59 "Changes the boundary IDs and/or boundary names for a given set of " 60 "boundaries defined by either boundary ID or boundary name. The " 61 "changes are independent of ordering. The merging of boundaries is supported.");
71 "Cannot use in combination with 'old_boundary_name'. Please use 'old_boundary' " 72 "instead; 'old_boundary_id' and 'old_boundary_name' are deprecated.");
75 "Cannot use in combination with 'new_boundary_name'. Please use 'new_boundary' " 76 "instead; 'new_boundary_id' and 'new_boundary_name' are deprecated.");
80 "Cannot use with 'old_boundary'. Use only 'old_boundary'; 'old_boundary_id' is " 85 "Cannot use with 'old_boundary_name'. Use only 'old_boundary'; 'old_boundary_id_name' is " 90 _old_boundary = getParam<std::vector<BoundaryName>>(
"old_boundary");
95 for (
const auto id :
getParam<std::vector<BoundaryID>>(
"old_boundary_id"))
101 _old_boundary = getParam<std::vector<BoundaryName>>(
"old_boundary_name");
107 _new_boundary = getParam<std::vector<BoundaryName>>(
"new_boundary");
112 for (
const auto id :
getParam<std::vector<BoundaryID>>(
"new_boundary_id"))
118 _new_boundary = getParam<std::vector<BoundaryName>>(
"new_boundary_name");
127 std::unique_ptr<MeshBase>
130 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
132 auto & boundary_info =
mesh->get_boundary_info();
136 std::set<BoundaryID> boundary_ids = boundary_info.get_boundary_ids();
139 mesh->comm().set_union(boundary_ids);
143 auto get_unused_boundary_id = [
this, &boundary_ids, &boundary_info]()
147 if (!boundary_ids.count(
id) && !boundary_info.get_sideset_name_map().count(
id) &&
148 !boundary_info.get_nodeset_name_map().count(
id))
150 boundary_ids.insert(
id);
160 const auto is_boundary_id = [](
const BoundaryName & boundary_name)
167 std::vector<std::string> old_boundary_names(num_boundaries);
168 std::stringstream missing_boundary;
169 for (std::size_t i = 0; i < num_boundaries; ++i)
175 old_boundary_ids[i] = id;
178 if (!boundary_ids.count(
id))
179 missing_boundary <<
name <<
" ";
183 if (is_boundary_id(
name))
185 old_boundary_names[i] = boundary_info.get_sideset_name(
id);
186 if (old_boundary_names[i].empty())
187 old_boundary_names[i] = boundary_info.get_nodeset_name(
id);
191 old_boundary_names[i] =
name;
193 if (missing_boundary.str().size())
195 "The following boundaries were requested to be renamed, but do not exist: ",
196 missing_boundary.str());
200 std::map<BoundaryID, std::string> new_names;
201 for (std::size_t i = 0; i < num_boundaries; ++i)
206 if (is_boundary_id(
name))
209 new_boundary_ids[i] = id;
213 boundary_ids.insert(
id);
216 if (old_boundary_names[i].size())
219 if (old_boundary_names[i] == std::to_string(old_boundary_ids[i]))
220 new_names[id] = std::to_string(new_boundary_ids[i]);
222 new_names[id] = old_boundary_names[i];
230 bool name_already_exists =
false;
234 for (
const auto map : {&boundary_info.set_sideset_name_map(),
235 &boundary_info.set_nodeset_name_map(),
237 for (
const auto & id_name_pair : *map)
238 if (!name_already_exists && id_name_pair.second ==
name)
240 new_boundary_ids[i] = id_name_pair.first;
241 new_names[id_name_pair.first] =
name;
242 name_already_exists =
true;
246 if (!name_already_exists)
248 new_boundary_ids[i] = old_boundary_ids[i];
249 new_names[new_boundary_ids[i]] =
name;
265 auto temp_new_boundary_ids = new_boundary_ids;
266 std::vector<std::pair<BoundaryID, BoundaryID>> temp_change_ids;
268 for (std::size_t new_i = 0; new_i < num_boundaries; ++new_i)
273 for (std::size_t old_i = new_i + 1; old_i < num_boundaries; ++old_i)
274 if (new_boundary_ids[new_i] == old_boundary_ids[old_i])
276 const auto temp_id = get_unused_boundary_id();
277 temp_change_ids.emplace_back(temp_id, new_boundary_ids[new_i]);
278 temp_new_boundary_ids[new_i] = temp_id;
284 for (std::size_t i = 0; i < num_boundaries; ++i)
285 MeshTools::Modification::change_boundary_id(
286 *
mesh, old_boundary_ids[i], temp_new_boundary_ids[i]);
289 for (
const auto & pair : temp_change_ids)
290 MeshTools::Modification::change_boundary_id(*
mesh, pair.first, pair.second);
293 for (std::size_t i = 0; i < num_boundaries; ++i)
295 if (boundary_info.get_sideset_name_map().count(old_boundary_ids[i]))
296 boundary_info.set_sideset_name_map().erase(old_boundary_ids[i]);
297 if (boundary_info.get_nodeset_name_map().count(old_boundary_ids[i]))
298 boundary_info.set_nodeset_name_map().erase(old_boundary_ids[i]);
302 for (
const auto & pair : new_names)
304 boundary_info.sideset_name(pair.first) = pair.second;
305 boundary_info.nodeset_name(pair.first) = pair.second;
308 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.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
Gets the boundary ID associated with the given BoundaryName.
boundary_id_type BoundaryID
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
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()
RenameBoundaryGenerator(const InputParameters ¶meters)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
std::string _new_boundary_param_name
The name of the parameter that specifies the new boundaries.
std::string _old_boundary_param_name
The name of the parameter that specifies the old boundaries.
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.