https://mooseframework.inl.gov
Loading...
Searching...
No Matches
RenumberBySubdomainGenerator.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
11#include "CastUniquePointer.h"
12#include "MooseMeshUtils.h"
13
15
18{
20
21 params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
22 params.addParam<std::vector<SubdomainName>>(
23 "blocks_to_renumber",
24 "Elements and nodes within these blocks will be renumbered. If none are specified, all "
25 "subdomains are affected by the renumbering");
26
27 params.addClassDescription("Changes the element and node IDs so that elements and nodes are "
28 "contiguous within a subdomain. Note that DoF ordering may be "
29 "affected as well, and that the mesh renumbering will be turned off.");
30
31 return params;
32}
33
35 : MeshGenerator(parameters), _input(getMesh("input"))
36{
37}
38
39std::unique_ptr<MeshBase>
41{
42 std::unique_ptr<MeshBase> mesh = std::move(_input);
43
44 // Not impossible to do.
45 if (!mesh->is_serial())
46 mooseError("Not implemented for non-serialized distributed meshes");
47
48 // Orphaned nodes would cause problems on renumbering, we are looping on the nodes attached
49 // to elements
50 mesh->remove_orphaned_nodes();
51 mesh->renumber_nodes_and_elements();
52
53 // Get the blocks provided by the user
54 std::optional<std::vector<SubdomainName>> blocks =
55 isParamValid("blocks_to_renumber")
56 ? getParam<std::vector<SubdomainName>>("blocks_to_renumber")
57 : std::vector<SubdomainName>();
58 std::vector<SubdomainID> block_ids(blocks->size());
59 std::stringstream missing_block;
60
61 for (const auto i : index_range(block_ids))
62 {
63 const SubdomainName & name = blocks.value()[i];
64
65 // Convert the SubdomainName to an id and store
66 const auto id = MooseMeshUtils::getSubdomainID(name, *mesh);
67 block_ids[i] = id;
68
69 // Block does not exist - store for a future error
71 missing_block << name << " ";
72 }
73 if (missing_block.str().size())
74 paramError("blocks_to_renumber",
75 "The following blocks were requested to be renumbered, but do not exist: ",
76 missing_block.str());
77
78 // User did not specify blocks, just get them all
79 if (blocks->empty())
80 {
81 std::set<subdomain_id_type> block_ids_set;
82 mesh->subdomain_ids(block_ids_set);
83 block_ids.reserve(block_ids_set.size());
84 block_ids.assign(block_ids_set.begin(), block_ids_set.end());
85
86 // Does not have useful data
87 blocks.reset();
88 }
89
90 // Renumber all elements with an ID we can recognize (so we can tell an already renumbered elem)
91 const auto max_elem_id = mesh->max_elem_id();
92 const auto max_node_id = mesh->max_node_id();
93 std::unordered_map<dof_id_type, dof_id_type> new_elem_ids;
94 new_elem_ids.reserve(max_elem_id);
95 std::unordered_set<dof_id_type> renumbered_nodes;
96 renumbered_nodes.reserve(max_node_id);
97
98 // Renumber block IDs one at a time
99 // We have to move them out of range, then back to range
100 dof_id_type elem_count = 0;
101 dof_id_type node_count = 0;
102 for (const auto i : index_range(block_ids))
103 {
104 for (auto elem : mesh->active_subdomain_elements_ptr_range(block_ids[i]))
105 {
106 // If we didn't specify all the subdomains, we might have to skip elem ids that are still
107 // taken
108 while (mesh->query_elem_ptr(elem_count))
109 {
110 elem_count++;
111 }
112 // We can't mess with the range while looping in them
113 new_elem_ids[elem->id()] = elem_count++;
114
115 for (auto & node : elem->node_ref_range())
116 // prevent re-renumbering
117 if (!renumbered_nodes.count(node.id()))
118 {
119 // If we didn't specify all the subdomains, we might have to skip node ids that are still
120 // taken
121 while (mesh->query_node_ptr(node_count))
122 {
123 node_count++;
124 }
125 renumbered_nodes.insert(node.id());
126 mesh->renumber_node(node.id(), node_count++);
127 }
128 }
129 }
130
131 // Now change the IDs
132 for (const auto [key, value] : new_elem_ids)
133 mesh->renumber_elem(key, value);
134
135 // Update the max ids
136 mesh->contract();
137
138 // Try to disallow renumbering from now on since we just renumbered
139 mesh->allow_renumbering(false);
140 // No gain if exodus just renumbers this. Better to tell the user
141 if (mesh->n_nodes() != mesh->max_node_id() || mesh->n_elem() != mesh->max_elem_id())
142 mooseWarning("Mesh is not contiguously numbered after renumbering. The numbering may be erased "
143 "by outputs that require contiguous numbering such as Exodus.\nNumber of nodes: " +
144 std::to_string(mesh->n_nodes()) +
145 "\nMax node ID: " + std::to_string(mesh->max_node_id() - 1) +
146 "\nNumber of elements: " + std::to_string(mesh->n_elem()) +
147 "\nMax elem ID: " + std::to_string(mesh->max_elem_id() - 1));
148
149 mesh->unset_is_prepared();
150 return dynamic_pointer_cast<MeshBase>(mesh);
151}
char ** blocks
registerMooseObject("MooseApp", RenumberBySubdomainGenerator)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object.
void addRequiredParam(const std::string &name, const std::string &doc_string)
This method adds a parameter and documentation string to the InputParameters object that will be extr...
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
MeshGenerators are objects that can modify or add to an existing mesh.
static InputParameters validParams()
const std::string & name() const
Get the name of the class.
Definition MooseBase.h:103
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition MooseBase.h:457
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...
Definition MooseBase.h:271
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition MooseBase.h:199
MeshGenerator for re-numbering elements and nodes contiguously within subdomains.
std::unique_ptr< MeshBase > & _input
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
RenumberBySubdomainGenerator(const InputParameters &parameters)
void mooseWarning(Args &&... args) const
MeshBase & mesh
SubdomainID getSubdomainID(const SubdomainName &subdomain_name, const MeshBase &mesh)
Gets the subdomain ID associated with the given SubdomainName.
const SubdomainID INVALID_BLOCK_ID
Definition MooseTypes.C:20