https://mooseframework.inl.gov
ElementGenerator.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 "ElementGenerator.h"
11 #include "CastUniquePointer.h"
12 
13 #include "libmesh/replicated_mesh.h"
14 #include "libmesh/string_to_enum.h"
15 #include "libmesh/face_c0polygon.h"
16 #include "libmesh/cell_c0polyhedron.h"
17 
18 #include "MooseEnum.h"
19 
21 
24 {
26 
27  MooseEnum elem_types(LIST_GEOM_ELEM); // no default
28 
29  params.addParam<MeshGeneratorName>("input", "Optional input mesh to add the elements to");
30 
31  // Element shape and location
32  params.addRequiredParam<std::vector<Point>>("nodal_positions",
33  "The x,y,z positions of the nodes");
34  params.addParam<std::vector<dof_id_type>>("element_connectivity",
35  "List of nodes to use for each element.");
36  params.addParam<std::vector<std::vector<dof_id_type>>>(
37  "polygon_faces_connectivity",
38  "List of nodes to use for each face of the polygon faces of the polyhedron. Only use this "
39  "parameter for a polyhedron 'elem_type'");
41  "elem_type", elem_types, "The type of element from libMesh to generate");
42 
43  // Subdomain
44  params.addParam<SubdomainName>("subdomain_name", "Subdomain name");
45  params.addParam<SubdomainID>("subdomain_id", 0, "Subdomain id");
46  // Sidesets
47  params.addParam<bool>("create_sidesets",
48  false,
49  "Create separate sidesets for each side. "
50  "The side index is used as the boundary ID for each sideset.");
51 
52  params.addClassDescription("Generates individual elements given a list of nodal positions.");
53 
54  return params;
55 }
56 
58  : MeshGenerator(parameters),
59  _input(getMesh("input", /* allow_invalid = */ true)),
60  _nodal_positions(getParam<std::vector<Point>>("nodal_positions")),
61  _element_connectivity(
62  isParamValid("polygon_faces_connectivity")
63  ? getParam<std::vector<std::vector<dof_id_type>>>("polygon_faces_connectivity")
64  : std::vector<std::vector<dof_id_type>>(
65  1, getParam<std::vector<dof_id_type>>("element_connectivity"))),
66  _elem_type(getParam<MooseEnum>("elem_type"))
67 {
68  if (_elem_type != "C0POLYHEDRON" && _element_connectivity.size() != 1)
69  paramError("element_connectivity", "Must be of size 1 for all element types but polyhedra");
70  if (isParamValid("polygon_faces_connectivity") && isParamValid("element_connectivity"))
71  paramError("element_connectivity",
72  "Either 'element_connectivity' or 'polygon_faces_connectivity' must be specified");
73 }
74 
75 std::unique_ptr<Elem>
76 ElementGenerator::getElemType(const std::string & type)
77 {
78  return Elem::build(Utility::string_to_enum<ElemType>(type));
79 }
80 
81 std::unique_ptr<MeshBase>
83 {
84  std::unique_ptr<MeshBase> mesh = std::move(_input);
85 
86  // If there was no input mesh then let's just make a new one
87  if (!mesh)
89 
90  // For polyhedra we need to know the side elements first
91  // For polygons we need to specify the number of sides/nodes
92  std::unique_ptr<Elem> elem;
93  if (_elem_type != "C0POLYGON" && _elem_type != "C0POLYHEDRON")
94  elem = getElemType(_elem_type);
95  else if (_elem_type == "C0POLYGON")
96  elem = std::make_unique<libMesh::C0Polygon>(_nodal_positions.size());
97 
98  std::vector<Node *> nodes;
99  nodes.reserve(_nodal_positions.size());
100 
101  // Add all the nodes to the mesh, keep pointers to them
102  for (const auto & point : _nodal_positions)
103  nodes.push_back(mesh->add_point(point));
104 
105  // Set the nodes in the element
106  if (_elem_type != "C0POLYHEDRON")
107  {
108  auto n = elem->n_nodes();
109  for (const auto j : make_range(n))
110  elem->set_node(j, nodes[_element_connectivity[0][j]]);
111  }
112  else
113  {
114  const auto n_sides = _element_connectivity.size();
115  // Create all the polygon sides
116  std::vector<std::shared_ptr<libMesh::Polygon>> sides;
117  sides.reserve(n_sides);
118  for (const auto i : make_range(n_sides))
119  {
120  auto side = std::make_shared<libMesh::C0Polygon>(_element_connectivity[i].size());
121  for (const auto i_node : index_range(_element_connectivity[i]))
122  side->set_node(i_node, nodes[_element_connectivity[i][i_node]]);
123  sides.push_back(side);
124  }
125 
126  // With the polygons we can create the polyhedron
127  std::unique_ptr<libMesh::Node> mid_elem_node;
128  elem = std::make_unique<libMesh::C0Polyhedron>(sides, mid_elem_node);
129  if (mid_elem_node)
130  mesh->add_node(std::move(mid_elem_node));
131  }
132 
133  // Subdomain information
134  elem->subdomain_id() = getParam<SubdomainID>("subdomain_id");
135  if (isParamValid("subdomain_name"))
136  mesh->subdomain_name(getParam<SubdomainID>("subdomain_id")) =
137  getParam<SubdomainName>("subdomain_name");
138 
139  mesh->set_mesh_dimension(std::max((unsigned int)elem->dim(), mesh->mesh_dimension()));
140 
141  if (getParam<bool>("create_sidesets"))
142  for (const auto i_side : make_range(elem->n_sides()))
143  mesh->get_boundary_info().add_side(elem.get(), i_side, i_side);
144 
145  mesh->add_elem(std::move(elem));
146  // We just added an element
147  mesh->unset_is_prepared();
148 
149  return dynamic_pointer_cast<MeshBase>(mesh);
150 }
void elem_types(const MeshBase &mesh, std::vector< ElemType > &et)
const std::string LIST_GEOM_ELEM
Definition: MooseMesh.h:62
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:467
std::unique_ptr< Elem > getElemType(const std::string &type)
Creates the base element of the given type.
std::unique_ptr< MeshBase > & _input
Mesh that possibly comes from another generator.
const std::vector< Point > & _nodal_positions
The nodal positions.
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
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.
const MooseEnum & _elem_type
The type of element to build.
ElementGenerator(const InputParameters &parameters)
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...
auto max(const L &left, const R &right)
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
char ** sides
Generates individual elements given a list of nodal positions.
registerMooseObject("MooseApp", ElementGenerator)
const std::string & type() const
Get the type of this class.
Definition: MooseBase.h:93
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:54
static InputParameters validParams()
Definition: MeshGenerator.C:23
static InputParameters validParams()
const std::vector< std::vector< dof_id_type > > _element_connectivity
The connectivity of the elements to the nodes.
IntRange< T > make_range(T beg, T end)
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...
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...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseBase.h:209
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
Build a MeshBase object whose underlying type will be determined by the Mesh input file block...
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:33
auto index_range(const T &sizable)
uint8_t dof_id_type