www.mooseframework.org
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
PatchSidesetGenerator Class Reference

Subdivides a sidesets into smaller patches each of which is going to be a new patch. More...

#include <PatchSidesetGenerator.h>

Inheritance diagram for PatchSidesetGenerator:
[legend]

Public Member Functions

 PatchSidesetGenerator (const InputParameters &parameters)
 
std::unique_ptr< MeshBase > generate () override
 

Static Public Member Functions

static InputParameters validParams ()
 

Protected Member Functions

std::vector< BoundaryName > sidesetNameHelper (const std::string &base_name) const
 returns the name of the _n_patches subdivisions derived from _sideset More...
 
Elem * boundaryElementHelper (MeshBase &mesh, libMesh::ElemType type) const
 

Protected Attributes

std::unique_ptr< MeshBase > & _input
 
unsigned int _n_patches
 the number of patches that this sideset generator divides _sideset into More...
 
const boundary_id_type & _sideset
 The sideset that will be subdivided. More...
 
MooseEnum _partitioner_name
 the name of the partitioner being used More...
 

Detailed Description

Subdivides a sidesets into smaller patches each of which is going to be a new patch.

Definition at line 25 of file PatchSidesetGenerator.h.

Constructor & Destructor Documentation

◆ PatchSidesetGenerator()

PatchSidesetGenerator::PatchSidesetGenerator ( const InputParameters &  parameters)

Definition at line 74 of file PatchSidesetGenerator.C.

75  : MeshGenerator(parameters),
76  _input(getMesh("input")),
77  _n_patches(getParam<unsigned int>("n_patches")),
78  _sideset(getParam<boundary_id_type>("sideset")),
79  _partitioner_name(getParam<MooseEnum>("partitioner"))
80 {
81 }

Member Function Documentation

◆ boundaryElementHelper()

Elem * PatchSidesetGenerator::boundaryElementHelper ( MeshBase &  mesh,
libMesh::ElemType  type 
) const
protected

Definition at line 236 of file PatchSidesetGenerator.C.

237 {
238  switch (type)
239  {
240  case 0:
241  return mesh.add_elem(new libMesh::Edge2);
242  case 1:
243  return mesh.add_elem(new libMesh::Edge3);
244  case 2:
245  return mesh.add_elem(new libMesh::Edge4);
246  case 3:
247  return mesh.add_elem(new libMesh::Tri3);
248  case 4:
249  return mesh.add_elem(new libMesh::Tri6);
250  case 5:
251  return mesh.add_elem(new libMesh::Quad4);
252  case 6:
253  return mesh.add_elem(new libMesh::Quad8);
254  case 7:
255  return mesh.add_elem(new libMesh::Quad9);
256  default:
257  mooseError("Unsupported element type (libMesh elem_type enum): ", type);
258  }
259 }

Referenced by generate().

◆ generate()

std::unique_ptr< MeshBase > PatchSidesetGenerator::generate ( )
override

Definition at line 84 of file PatchSidesetGenerator.C.

85 {
86  std::unique_ptr<MeshBase> mesh = std::move(_input);
87 
88  _mesh->errorIfDistributedMesh("PatchSidesetGenerator");
89 
90  // Get a reference to our BoundaryInfo object for later use
91  BoundaryInfo & boundary_info = mesh->get_boundary_info();
92 
93  // get a list of all sides; vector of tuples (elem, loc_side, side_set)
94  auto side_list = boundary_info.build_active_side_list();
95 
96  // create a dim - 1 dimensional mesh
97  auto boundary_mesh =
98  libmesh_make_unique<libMesh::ReplicatedMesh>(comm(), mesh->mesh_dimension() - 1);
99  boundary_mesh->set_mesh_dimension(mesh->mesh_dimension() - 1);
100  boundary_mesh->set_spatial_dimension(mesh->mesh_dimension());
101 
102  // nodes in the new mesh by boundary_node_id (index)
103  std::vector<Node *> boundary_nodes;
104  // a map from the node numbering on the volumetric mesh to the numbering
105  // on the boundary_mesh
106  std::map<dof_id_type, dof_id_type> mesh_node_id_to_boundary_node_id;
107  // a local counter keeping track of how many entries have been added to boundary_nodes
108  dof_id_type boundary_node_id = 0;
109  // a map from new element id in the boundary mesh to the element id/side/sideset
110  // tuple it came from
111  std::map<dof_id_type, std::tuple<dof_id_type, unsigned short int, boundary_id_type>>
112  boundary_elem_to_mesh_elem;
113  for (auto & side : side_list)
114  {
115  if (std::get<2>(side) == _sideset)
116  {
117  // the original volumetric mesh element
118  const Elem * elem = mesh->elem_ptr(std::get<0>(side));
119 
120  // the boundary element
121  std::unique_ptr<const Elem> boundary_elem = elem->side_ptr(std::get<1>(side));
122 
123  // an array that saves the boundary node ids of this elem in the right order
124  std::vector<dof_id_type> bnd_elem_node_ids(boundary_elem->n_nodes());
125 
126  // loop through the nodes in boundary_elem
127  for (unsigned int j = 0; j < boundary_elem->n_nodes(); ++j)
128  {
129  const Node * node = boundary_elem->node_ptr(j);
130 
131  // Is this node a new node?
132  if (mesh_node_id_to_boundary_node_id.find(node->id()) ==
133  mesh_node_id_to_boundary_node_id.end())
134  {
135  // yes, it is new, need to add it to the mesh_node_id_to_boundary_node_id map
136  mesh_node_id_to_boundary_node_id.insert(
137  std::pair<dof_id_type, dof_id_type>(node->id(), boundary_node_id));
138 
139  // this adds this node to the boundary mesh and puts it at the right position
140  // in the boundary_nodes array
141  Point pt(*node);
142  boundary_nodes.push_back(boundary_mesh->add_point(pt, boundary_node_id));
143 
144  // keep track of the boundary node for setting up the element
145  bnd_elem_node_ids[j] = boundary_node_id;
146 
147  // increment the boundary_node_id counter
148  ++boundary_node_id;
149  }
150  else
151  bnd_elem_node_ids[j] = mesh_node_id_to_boundary_node_id.find(node->id())->second;
152  }
153 
154  // all nodes for this element have been added, so we can add the element to the
155  // boundary mesh
156  Elem * new_bnd_elem = boundaryElementHelper(*boundary_mesh, boundary_elem->type());
157 
158  // keep track of these new boundary elements in boundary_elem_to_mesh_elem
159  boundary_elem_to_mesh_elem.insert(
160  std::pair<dof_id_type, std::tuple<dof_id_type, unsigned short int, boundary_id_type>>(
161  new_bnd_elem->id(), side));
162 
163  // set the nodes & subdomain_id of the new element by looping over the
164  // boundary_elem and then inserting its nodes into new_bnd_elem in the
165  // same order
166  for (unsigned int j = 0; j < boundary_elem->n_nodes(); ++j)
167  {
168  dof_id_type old_node_id = boundary_elem->node_ptr(j)->id();
169  if (mesh_node_id_to_boundary_node_id.find(old_node_id) ==
170  mesh_node_id_to_boundary_node_id.end())
171  mooseError("Node id", old_node_id, " not linked to new node id.");
172  dof_id_type new_node_id = mesh_node_id_to_boundary_node_id.find(old_node_id)->second;
173  new_bnd_elem->set_node(j) = boundary_nodes[new_node_id];
174  }
175  }
176  }
177 
178  // partition the boundary mesh
179  boundary_mesh->prepare_for_use();
180  MooseMesh::setPartitioner(*boundary_mesh, _partitioner_name, false, _pars, *this);
181  boundary_mesh->partition(_n_patches);
182 
183  // prepare sideset names and boundary_ids added to mesh
184  std::vector<BoundaryName> sideset_names =
185  sidesetNameHelper(boundary_info.get_sideset_name(_sideset));
186 
187  std::vector<boundary_id_type> boundary_ids =
188  MooseMeshUtils::getBoundaryIDs(*mesh, sideset_names, true);
189 
190  mooseAssert(sideset_names.size() == _n_patches,
191  "sideset_names must have as many entries as user-requested number of patches.");
192  mooseAssert(boundary_ids.size() == _n_patches,
193  "boundary_ids must have as many entries as user-requested number of patches.");
194 
195  // loop through all elements in the boundary mesh and assign the side of
196  // the _original_ element to the new sideset
197  for (const auto & elem : boundary_mesh->active_element_ptr_range())
198  {
199  if (boundary_elem_to_mesh_elem.find(elem->id()) == boundary_elem_to_mesh_elem.end())
200  mooseError("Element in the boundary mesh with id ",
201  elem->id(),
202  " not found in boundary_elem_to_mesh_elem.");
203 
204  auto side = boundary_elem_to_mesh_elem.find(elem->id())->second;
205 
206  mooseAssert(elem->processor_id() < boundary_ids.size(),
207  "Processor id larger than number of patches.");
208  boundary_info.add_side(
209  std::get<0>(side), std::get<1>(side), boundary_ids[elem->processor_id()]);
210  }
211 
212  // make sure new boundary names are set
213  for (unsigned int j = 0; j < boundary_ids.size(); ++j)
214  {
215  boundary_info.sideset_name(boundary_ids[j]) = sideset_names[j];
216  boundary_info.nodeset_name(boundary_ids[j]) = sideset_names[j];
217  }
218 
219  return mesh;
220 }

◆ sidesetNameHelper()

std::vector< BoundaryName > PatchSidesetGenerator::sidesetNameHelper ( const std::string &  base_name) const
protected

returns the name of the _n_patches subdivisions derived from _sideset

Definition at line 223 of file PatchSidesetGenerator.C.

224 {
225  std::vector<BoundaryName> rv;
226  for (unsigned int j = 0; j < _n_patches; ++j)
227  {
228  std::stringstream ss;
229  ss << base_name << "_" << j;
230  rv.push_back(ss.str());
231  }
232  return rv;
233 }

Referenced by generate().

◆ validParams()

InputParameters PatchSidesetGenerator::validParams ( )
static

Definition at line 44 of file PatchSidesetGenerator.C.

45 {
46  InputParameters params = MeshGenerator::validParams();
47 
48  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
49  params.addRequiredParam<boundary_id_type>("sideset",
50  "The sideset that will be divided into patches");
51  params.addRequiredRangeCheckedParam<unsigned int>(
52  "n_patches", "n_patches>0", "Number of patches");
53 
54  MooseEnum partitioning("default=-3 metis=-2 parmetis=-1 linear=0 centroid hilbert_sfc morton_sfc",
55  "default");
56  params.addParam<MooseEnum>(
57  "partitioner",
58  partitioning,
59  "Specifies a mesh partitioner to use when splitting the mesh for a parallel computation.");
60  MooseEnum direction("x y z radial");
61  params.addParam<MooseEnum>("centroid_partitioner_direction",
62  direction,
63  "Specifies the sort direction if using the centroid partitioner. "
64  "Available options: x, y, z, radial");
65 
66  params.addParamNamesToGroup("partitioner centroid_partitioner_direction", "Partitioning");
67 
68  params.addClassDescription(
69  "Divides the given sideset into smaller patches of roughly equal size.");
70 
71  return params;
72 }

Member Data Documentation

◆ _input

std::unique_ptr<MeshBase>& PatchSidesetGenerator::_input
protected

Definition at line 40 of file PatchSidesetGenerator.h.

Referenced by generate().

◆ _n_patches

unsigned int PatchSidesetGenerator::_n_patches
protected

the number of patches that this sideset generator divides _sideset into

Definition at line 43 of file PatchSidesetGenerator.h.

Referenced by generate(), and sidesetNameHelper().

◆ _partitioner_name

MooseEnum PatchSidesetGenerator::_partitioner_name
protected

the name of the partitioner being used

Definition at line 49 of file PatchSidesetGenerator.h.

Referenced by generate().

◆ _sideset

const boundary_id_type& PatchSidesetGenerator::_sideset
protected

The sideset that will be subdivided.

Definition at line 46 of file PatchSidesetGenerator.h.

Referenced by generate().


The documentation for this class was generated from the following files:
PatchSidesetGenerator::_n_patches
unsigned int _n_patches
the number of patches that this sideset generator divides _sideset into
Definition: PatchSidesetGenerator.h:43
PatchSidesetGenerator::boundaryElementHelper
Elem * boundaryElementHelper(MeshBase &mesh, libMesh::ElemType type) const
Definition: PatchSidesetGenerator.C:236
PatchSidesetGenerator::_partitioner_name
MooseEnum _partitioner_name
the name of the partitioner being used
Definition: PatchSidesetGenerator.h:49
PatchSidesetGenerator::sidesetNameHelper
std::vector< BoundaryName > sidesetNameHelper(const std::string &base_name) const
returns the name of the _n_patches subdivisions derived from _sideset
Definition: PatchSidesetGenerator.C:223
validParams
InputParameters validParams()
PatchSidesetGenerator::_sideset
const boundary_id_type & _sideset
The sideset that will be subdivided.
Definition: PatchSidesetGenerator.h:46
PatchSidesetGenerator::_input
std::unique_ptr< MeshBase > & _input
Definition: PatchSidesetGenerator.h:40