https://mooseframework.inl.gov
NodeSetsGeneratorBase.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 
10 #include "NodeSetsGeneratorBase.h"
11 #include "Parser.h"
12 #include "InputParameters.h"
13 #include "MooseMeshUtils.h"
14 
15 #include "libmesh/mesh_generation.h"
16 #include "libmesh/mesh.h"
17 #include "libmesh/elem.h"
18 
21 {
23  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
24  params.addRequiredParam<std::vector<BoundaryName>>("new_nodeset",
25  "The list of nodeset names to create.");
26 
27  params.addParam<bool>("replace",
28  false,
29  "If true, replace the old nodesets. If false, the current nodesets (if "
30  "any) will be preserved.");
31 
32  params.addParam<std::vector<BoundaryName>>(
33  "included_nodesets",
34  "A set of nodeset names or ids whose nodes will be included in the new nodesets. A node "
35  "is only added if it also belongs to one of these nodesets.");
36  params.addParam<std::vector<BoundaryName>>(
37  "excluded_nodesets",
38  "A set of nodeset names or ids whose nodes will be excluded from the new nodesets. A node "
39  "is only added if does not belong to any of these nodesets.");
40  params.addParam<std::vector<SubdomainName>>(
41  "included_subdomains",
42  "A set of subdomain names or ids whose nodes will be included in the new nodesets. A node "
43  "is only added if the subdomain id of the corresponding element is in this set.");
44  params.addParam<std::vector<SubdomainName>>(
45  "excluded_subdomains",
46  "A set of subdomain names or ids whose nodes will be excluded in the new nodesets. A node "
47  "is only added if the subdomain id of the corresponding element is not in this set.");
48 
49  params.addParam<bool>(
50  "include_only_external_nodes",
51  false,
52  "Whether to only include external nodes when considering nodes to add to the nodeset");
53 
54  // Nodeset restriction param group
55  params.addParamNamesToGroup("included_nodesets excluded_nodesets included_subdomains "
56  "include_only_external_nodes",
57  "Nodeset restrictions");
58 
59  return params;
60 }
61 
63  : MeshGenerator(parameters),
64  _input(getMesh("input")),
65  _nodeset_names(std::vector<BoundaryName>()),
66  _replace(getParam<bool>("replace")),
67  _check_included_nodesets(isParamValid("included_nodesets")),
68  _check_excluded_nodesets(isParamValid("excluded_nodesets")),
69  _check_included_subdomains(isParamValid("included_subdomains")),
70  _check_excluded_subdomains(isParamValid("excluded_subdomains")),
71  _included_nodeset_ids(std::vector<boundary_id_type>()),
72  _excluded_nodeset_ids(std::vector<boundary_id_type>()),
73  _included_subdomain_ids(std::vector<subdomain_id_type>()),
74  _excluded_subdomain_ids(std::vector<subdomain_id_type>()),
75  _include_only_external_nodes(getParam<bool>("include_only_external_nodes"))
76 {
77  if (isParamValid("new_nodeset"))
78  _nodeset_names = getParam<std::vector<BoundaryName>>("new_nodeset");
79 }
80 
81 void
83 {
84  // Parameter checks and filling vector of ids (used instead of names for efficiency)
86  {
87  const auto & included_nodesets = getParam<std::vector<BoundaryName>>("included_nodesets");
88  for (const auto & nodeset_name : _nodeset_names)
89  if (std::find(included_nodesets.begin(), included_nodesets.end(), nodeset_name) !=
90  included_nodesets.end())
91  paramError(
92  "new_nodeset",
93  "A nodeset cannot be both the new nodeset and be included in the list of included "
94  "nodesets. If you are trying to restrict an existing nodeset, you must use a "
95  "different name for 'new_nodeset', delete the old nodeset, and then rename the "
96  "new nodeset to the old nodeset.");
97 
98  _included_nodeset_ids = MooseMeshUtils::getBoundaryIDs(mesh, included_nodesets, false);
99 
100  // Check that the included nodeset ids/names exist in the mesh
101  for (const auto i : index_range(_included_nodeset_ids))
103  paramError("included_nodesets",
104  "The nodeset '",
105  included_nodesets[i],
106  "' was not found within the mesh");
107  }
108 
110  {
111  const auto & excluded_nodesets = getParam<std::vector<BoundaryName>>("excluded_nodesets");
112  for (const auto & nodeset_name : _nodeset_names)
113  if (std::find(excluded_nodesets.begin(), excluded_nodesets.end(), nodeset_name) !=
114  excluded_nodesets.end())
115  paramError(
116  "new_nodeset",
117  "A nodeset cannot be both the new nodeset and be excluded in the list of excluded "
118  "nodesets.");
119  _excluded_nodeset_ids = MooseMeshUtils::getBoundaryIDs(mesh, excluded_nodesets, false);
120 
121  // Check that the excluded nodeset ids/names exist in the mesh
122  for (const auto i : index_range(_excluded_nodeset_ids))
124  paramError("excluded_nodesets",
125  "The nodeset '",
126  excluded_nodesets[i],
127  "' was not found within the mesh");
128 
130  {
131  // Check that included and excluded nodeset lists do not overlap
132  for (const auto & nodeset_id : _included_nodeset_ids)
133  if (std::find(_excluded_nodeset_ids.begin(), _excluded_nodeset_ids.end(), nodeset_id) !=
134  _excluded_nodeset_ids.end())
135  paramError("excluded_nodesets",
136  "'included_nodesets' and 'excluded_nodesets' lists should not overlap");
137  }
138  }
139 
140  // Get the subdomain ids from the names
142  {
143  // check that the subdomains exist in the mesh
144  const auto subdomains = getParam<std::vector<SubdomainName>>("included_subdomains");
145  for (const auto & name : subdomains)
147  paramError("included_subdomains", "The block '", name, "' was not found in the mesh");
148 
150  }
151 
153  {
154  // check that the subdomains exist in the mesh
155  const auto subdomains = getParam<std::vector<SubdomainName>>("excluded_subdomains");
156  for (const auto & name : subdomains)
158  paramError("excluded_subdomains", "The block '", name, "' was not found in the mesh");
159 
161 
163  {
164  // Check that included and excluded nodeset lists do not overlap
165  for (const auto & subdomain_id : _included_subdomain_ids)
166  if (std::find(_excluded_subdomain_ids.begin(),
168  subdomain_id) != _excluded_subdomain_ids.end())
169  paramError("excluded_subdomains",
170  "'included_subdomains' and 'excluded_subdomains' lists should not overlap");
171  }
172  }
173 
174  // Build the node to element map, which is usually provided by a MooseMesh but in the mesh
175  // generation process we are working with a MeshBase
176  for (const auto & elem : mesh.active_element_ptr_range())
177  for (unsigned int n = 0; n < elem->n_nodes(); n++)
178  _node_to_elem_map[elem->node_id(n)].push_back(elem->id());
179 }
180 
181 bool
183  const std::vector<dof_id_type> & node_elems,
184  const MeshBase & mesh) const
185 {
186  // Loop on the elements and check whether the node is part of a side with no neighbor (exterior)
187  for (const auto elem_id : node_elems)
188  {
189  const auto elem = mesh.elem_ptr(elem_id);
190  for (const auto side_i : make_range(elem->n_sides()))
191  {
192  // Node is part of the side
193  if (elem->side_ptr(side_i)->get_node_index(node) != libMesh::invalid_uint)
194  {
195  // No neighbor on that side
196  if (!elem->neighbor_ptr(side_i))
197  return true;
198  }
199  }
200  }
201  return false;
202 }
203 
204 bool
205 NodeSetsGeneratorBase::nodeElementsInIncludedSubdomains(const std::vector<dof_id_type> node_elems,
206  const MeshBase & mesh) const
207 {
208  for (const auto elem_id : node_elems)
209  {
210  subdomain_id_type curr_subdomain = mesh.elem_ptr(elem_id)->subdomain_id();
211  if (std ::find(_included_subdomain_ids.begin(),
213  curr_subdomain) != _included_subdomain_ids.end())
214  return true;
215  }
216  return false;
217 }
218 
219 bool
220 NodeSetsGeneratorBase::nodeElementsInExcludedSubdomains(const std::vector<dof_id_type> node_elems,
221  const MeshBase & mesh) const
222 {
223  for (const auto elem_id : node_elems)
224  {
225  subdomain_id_type curr_subdomain = mesh.elem_ptr(elem_id)->subdomain_id();
226  if (std ::find(_excluded_subdomain_ids.begin(),
228  curr_subdomain) != _excluded_subdomain_ids.end())
229  return true;
230  }
231  return false;
232 }
233 
234 bool
235 NodeSetsGeneratorBase::nodeInIncludedNodesets(const std::vector<BoundaryID> & node_nodesets) const
236 {
237  for (const auto bid : node_nodesets)
238  if (std::find(_included_nodeset_ids.begin(), _included_nodeset_ids.end(), bid) !=
239  _included_nodeset_ids.end())
240  return true;
241  return false;
242 }
243 
244 bool
245 NodeSetsGeneratorBase::nodeInExcludedNodesets(const std::vector<BoundaryID> & node_nodesets) const
246 {
247  for (const auto bid : node_nodesets)
248  if (std::find(_excluded_nodeset_ids.begin(), _excluded_nodeset_ids.end(), bid) !=
249  _excluded_nodeset_ids.end())
250  return true;
251  return false;
252 }
253 
254 bool
256  const std::vector<BoundaryID> & node_nodesets,
257  const std::vector<dof_id_type> & node_elems,
258  const MeshBase & mesh) const
259 {
260  // Skip if side has neighbor and we only want external nodes
262  return false;
263 
264  // Skip if none of the elements owning the node are in the list of accepted subdomains
266  return false;
267 
268  // Skip if a element owning the node is in the list of excluded subdomains
269  // Note: if a node is on the interface of included subdomains and excluded subdomains,
270  // it will pass the above check but return false here, i.e. subdomain excluding will
271  // win if both subdomain including and excluding are true.
273  return false;
274 
275  // Skip if side is not part of included nodesets
276  if (_check_included_nodesets && !nodeInIncludedNodesets(node_nodesets))
277  return false;
278 
279  // Skip if side is part of excluded nodesets
280  if (_check_excluded_nodesets && nodeInExcludedNodesets(node_nodesets))
281  return false;
282 
283  return true;
284 }
const bool _check_excluded_nodesets
whether to check nodeset ids against the excluded nodeset list when adding nodes or not ...
const bool _check_excluded_subdomains
whether to check subdomain ids of the element that excluded this node
const bool _check_included_subdomains
whether to check subdomain ids of the element that included this node
const unsigned int invalid_uint
std::vector< subdomain_id_type > _excluded_subdomain_ids
A list of included subdomain ids that the node must not be part of, extracted from the excluded_subdo...
const BoundaryID INVALID_BOUNDARY_ID
Definition: MooseTypes.C:22
bool nodeSatisfiesRequirements(const Node *node, const std::vector< BoundaryID > &node_nodesets, const std::vector< dof_id_type > &node_elems, const MeshBase &mesh) const
Determines whether the given node satisfies the user-specified constraints.
MeshBase & mesh
const bool _check_included_nodesets
whether to check nodeset ids against the included nodeset list when adding nodes or not ...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
bool nodeInExcludedNodesets(const std::vector< BoundaryID > &node_nodesets) const
Determines whether the given node of an element belongs to any nodesets in the excluded_nodesets para...
std::vector< subdomain_id_type > getSubdomainIDs(const libMesh::MeshBase &mesh, const std::vector< SubdomainName > &subdomain_name)
Get the associated subdomainIDs for the subdomain names that are passed in.
virtual const std::string & name() const
Get the name of the class.
Definition: MooseBase.h:57
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...
std::vector< BoundaryName > _nodeset_names
The list of new nodeset names.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
bool nodeInIncludedNodesets(const std::vector< BoundaryID > &node_nodesets) const
Determines whether the given node belongs to any nodesets in the included_nodesets parameter...
int8_t boundary_id_type
bool nodeOnMeshExteriorBoundary(const Node *node, const std::vector< dof_id_type > &node_elems, const MeshBase &mesh) const
Determines whether the node is on the exterior of the mesh.
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
Gets the boundary IDs with their names.
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 ...
static InputParameters validParams()
Definition: MeshGenerator.C:23
bool hasSubdomainName(const MeshBase &input_mesh, const SubdomainName &name)
Whether a particular subdomain name exists in the mesh.
std::vector< boundary_id_type > _excluded_nodeset_ids
A list of nodeset ids that the node must not be a part of, extracted from the excluded_nodesets param...
const bool _include_only_external_nodes
Whether to only include external node when considering nodes to add to the nodeset.
bool nodeElementsInExcludedSubdomains(const std::vector< dof_id_type > node_elems, const MeshBase &mesh) const
Determines whether any neighbor element of the node has a subdomain id in the given excluded_subdomai...
IntRange< T > make_range(T beg, T end)
std::unordered_map< dof_id_type, std::vector< dof_id_type > > _node_to_elem_map
A map from nodes (ids) to local elements (ids) which comprise the node.
void setup(MeshBase &mesh)
This method prepares a few attributes which are commonly needed for nodeset generation such as a map ...
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...
NodeSetsGeneratorBase(const InputParameters &parameters)
static InputParameters validParams()
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:32
auto index_range(const T &sizable)
std::vector< boundary_id_type > _included_nodeset_ids
A list of nodeset ids that the node has to be part of, extracted from the included_nodesets parameter...
bool nodeElementsInIncludedSubdomains(const std::vector< dof_id_type > node_elems, const MeshBase &mesh) const
Determines whether any neighbor element of the node has a subdomain id in the given included_subdomai...
std::vector< subdomain_id_type > _included_subdomain_ids
A list of included subdomain ids that the node has to be part of, extracted from the included_subdoma...
void addParamNamesToGroup(const std::string &space_delim_names, const std::string group_name)
This method takes a space delimited list of parameter names and adds them to the specified group name...