www.mooseframework.org
GeneratedMeshGenerator.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 "GeneratedMeshGenerator.h"
11 #include "CastUniquePointer.h"
12 
13 #include "libmesh/replicated_mesh.h"
14 #include "libmesh/mesh_generation.h"
15 #include "libmesh/string_to_enum.h"
16 #include "libmesh/periodic_boundaries.h"
17 #include "libmesh/periodic_boundary_base.h"
18 #include "libmesh/unstructured_mesh.h"
19 #include "libmesh/elem.h"
20 
21 // C++ includes
22 #include <cmath> // provides round, not std::round (see http://www.cplusplus.com/reference/cmath/round/)
23 
25 
27 
30 {
32 
33  MooseEnum elem_types(
34  "EDGE EDGE2 EDGE3 EDGE4 QUAD QUAD4 QUAD8 QUAD9 TRI3 TRI6 HEX HEX8 HEX20 HEX27 TET4 TET10 "
35  "PRISM6 PRISM15 PRISM18 PYRAMID5 PYRAMID13 PYRAMID14"); // no default
36 
37  MooseEnum dims("1=1 2 3");
38  params.addRequiredParam<MooseEnum>("dim", dims, "The dimension of the mesh to be generated");
39 
40  params.addParam<unsigned int>("nx", 1, "Number of elements in the X direction");
41  params.addParam<unsigned int>("ny", 1, "Number of elements in the Y direction");
42  params.addParam<unsigned int>("nz", 1, "Number of elements in the Z direction");
43  params.addParam<Real>("xmin", 0.0, "Lower X Coordinate of the generated mesh");
44  params.addParam<Real>("ymin", 0.0, "Lower Y Coordinate of the generated mesh");
45  params.addParam<Real>("zmin", 0.0, "Lower Z Coordinate of the generated mesh");
46  params.addParam<Real>("xmax", 1.0, "Upper X Coordinate of the generated mesh");
47  params.addParam<Real>("ymax", 1.0, "Upper Y Coordinate of the generated mesh");
48  params.addParam<Real>("zmax", 1.0, "Upper Z Coordinate of the generated mesh");
49  params.addParam<MooseEnum>("elem_type",
50  elem_types,
51  "The type of element from libMesh to "
52  "generate (default: linear element for "
53  "requested dimension)");
54  params.addParam<bool>(
55  "gauss_lobatto_grid",
56  false,
57  "Grade mesh into boundaries according to Gauss-Lobatto quadrature spacing.");
58  params.addRangeCheckedParam<Real>(
59  "bias_x",
60  1.,
61  "bias_x>=0.5 & bias_x<=2",
62  "The amount by which to grow (or shrink) the cells in the x-direction.");
63  params.addRangeCheckedParam<Real>(
64  "bias_y",
65  1.,
66  "bias_y>=0.5 & bias_y<=2",
67  "The amount by which to grow (or shrink) the cells in the y-direction.");
68  params.addRangeCheckedParam<Real>(
69  "bias_z",
70  1.,
71  "bias_z>=0.5 & bias_z<=2",
72  "The amount by which to grow (or shrink) the cells in the z-direction.");
73 
74  params.addParamNamesToGroup("dim", "Main");
75 
76  params.addParam<std::vector<ExtraElementIDName>>("extra_element_integers",
77  "Names of extra element integers");
78 
79  params.addClassDescription(
80  "Create a line, square, or cube mesh with uniformly spaced or biased elements.");
81 
82  return params;
83 }
84 
86  : MeshGenerator(parameters),
87  _dim(getParam<MooseEnum>("dim")),
88  _nx(declareMeshProperty("num_elements_x", getParam<unsigned int>("nx"))),
89  _ny(declareMeshProperty("num_elements_y", getParam<unsigned int>("ny"))),
90  _nz(declareMeshProperty("num_elements_z", getParam<unsigned int>("nz"))),
91  _xmin(declareMeshProperty("xmin", getParam<Real>("xmin"))),
92  _xmax(declareMeshProperty("xmax", getParam<Real>("xmax"))),
93  _ymin(declareMeshProperty("ymin", getParam<Real>("ymin"))),
94  _ymax(declareMeshProperty("ymax", getParam<Real>("ymax"))),
95  _zmin(declareMeshProperty("zmin", getParam<Real>("zmin"))),
96  _zmax(declareMeshProperty("zmax", getParam<Real>("zmax"))),
97  _gauss_lobatto_grid(getParam<bool>("gauss_lobatto_grid")),
98  _bias_x(getParam<Real>("bias_x")),
99  _bias_y(getParam<Real>("bias_y")),
100  _bias_z(getParam<Real>("bias_z"))
101 {
102  if (_gauss_lobatto_grid && (_bias_x != 1.0 || _bias_y != 1.0 || _bias_z != 1.0))
103  mooseError("Cannot apply both Gauss-Lobatto mesh grading and biasing at the same time.");
104 }
105 
106 std::unique_ptr<MeshBase>
108 {
109  // Have MOOSE construct the correct libMesh::Mesh object using Mesh block and CLI parameters.
110  auto mesh = _mesh->buildMeshBaseObject();
111 
112  if (isParamValid("extra_element_integers"))
113  {
114  for (auto & name : getParam<std::vector<ExtraElementIDName>>("extra_element_integers"))
115  mesh->add_elem_integer(name);
116  }
117 
118  MooseEnum elem_type_enum = getParam<MooseEnum>("elem_type");
119 
120  if (!isParamValid("elem_type"))
121  {
122  // Switching on MooseEnum
123  switch (_dim)
124  {
125  case 1:
126  elem_type_enum = "EDGE2";
127  break;
128  case 2:
129  elem_type_enum = "QUAD4";
130  break;
131  case 3:
132  elem_type_enum = "HEX8";
133  break;
134  }
135  }
136 
137  ElemType elem_type = Utility::string_to_enum<ElemType>(elem_type_enum);
138 
139  // Switching on MooseEnum
140  switch (_dim)
141  {
142  // The build_XYZ mesh generation functions take an
143  // UnstructuredMesh& as the first argument, hence the dynamic_cast.
144  case 1:
145  MeshTools::Generation::build_line(static_cast<UnstructuredMesh &>(*mesh),
146  _nx,
147  _xmin,
148  _xmax,
149  elem_type,
151  break;
152  case 2:
153  MeshTools::Generation::build_square(static_cast<UnstructuredMesh &>(*mesh),
154  _nx,
155  _ny,
156  _xmin,
157  _xmax,
158  _ymin,
159  _ymax,
160  elem_type,
162  break;
163  case 3:
164  MeshTools::Generation::build_cube(static_cast<UnstructuredMesh &>(*mesh),
165  _nx,
166  _ny,
167  _nz,
168  _xmin,
169  _xmax,
170  _ymin,
171  _ymax,
172  _zmin,
173  _zmax,
174  elem_type,
176  break;
177  }
178 
179  // Apply the bias if any exists
180  if (_bias_x != 1.0 || _bias_y != 1.0 || _bias_z != 1.0)
181  {
182  const auto MIN = std::numeric_limits<Real>::max();
183 
184  // Biases
185  std::array<Real, LIBMESH_DIM> bias = {
186  {_bias_x, _dim > 1 ? _bias_y : 1.0, _dim > 2 ? _bias_z : 1.0}};
187 
188  // "width" of the mesh in each direction
189  std::array<Real, LIBMESH_DIM> width = {
190  {_xmax - _xmin, _dim > 1 ? _ymax - _ymin : 0, _dim > 2 ? _zmax - _zmin : 0}};
191 
192  // Min mesh extent in each direction.
193  std::array<Real, LIBMESH_DIM> mins = {{_xmin, _dim > 1 ? _ymin : MIN, _dim > 2 ? _zmin : MIN}};
194 
195  // Number of elements in each direction.
196  std::array<unsigned int, LIBMESH_DIM> nelem = {{_nx, _dim > 1 ? _ny : 1, _dim > 2 ? _nz : 1}};
197 
198  // We will need the biases raised to integer powers in each
199  // direction, so let's pre-compute those...
200  std::array<std::vector<Real>, LIBMESH_DIM> pows;
201  for (unsigned int dir = 0; dir < LIBMESH_DIM; ++dir)
202  {
203  pows[dir].resize(nelem[dir] + 1);
204  for (unsigned int i = 0; i < pows[dir].size(); ++i)
205  pows[dir][i] = std::pow(bias[dir], static_cast<int>(i));
206  }
207 
208  // Loop over the nodes and move them to the desired location
209  for (auto & node_ptr : mesh->node_ptr_range())
210  {
211  Node & node = *node_ptr;
212 
213  for (unsigned int dir = 0; dir < LIBMESH_DIM; ++dir)
214  {
215  if (width[dir] != 0. && bias[dir] != 1.)
216  {
217  // Compute the scaled "index" of the current point. This
218  // will either be close to a whole integer or a whole
219  // integer+0.5 for quadratic nodes.
220  Real float_index = (node(dir) - mins[dir]) * nelem[dir] / width[dir];
221 
222  Real integer_part = 0;
223  Real fractional_part = std::modf(float_index, &integer_part);
224 
225  // Figure out where to move the node...
226  if (std::abs(fractional_part) < TOLERANCE || std::abs(fractional_part - 1.0) < TOLERANCE)
227  {
228  // If the fractional_part ~ 0.0 or 1.0, this is a vertex node, so
229  // we don't need an average.
230  //
231  // Compute the "index" we are at in the current direction. We
232  // round to the nearest integral value to get this instead
233  // of using "integer_part", since that could be off by a
234  // lot (e.g. we want 3.9999 to map to 4.0 instead of 3.0).
235  int index = round(float_index);
236 
237  mooseAssert(index >= static_cast<int>(0) && index < static_cast<int>(pows[dir].size()),
238  "Scaled \"index\" out of range");
239 
240  // Move node to biased location.
241  node(dir) =
242  mins[dir] + width[dir] * (1. - pows[dir][index]) / (1. - pows[dir][nelem[dir]]);
243  }
244  else if (std::abs(fractional_part - 0.5) < TOLERANCE)
245  {
246  // If the fractional_part ~ 0.5, this is a midedge/face
247  // (i.e. quadratic) node. We don't move those with the same
248  // bias as the vertices, instead we put them midway between
249  // their respective vertices.
250  //
251  // Also, since the fractional part is nearly 0.5, we know that
252  // the integer_part will be the index of the vertex to the
253  // left, and integer_part+1 will be the index of the
254  // vertex to the right.
255  node(dir) = mins[dir] +
256  width[dir] *
257  (1. - 0.5 * (pows[dir][integer_part] + pows[dir][integer_part + 1])) /
258  (1. - pows[dir][nelem[dir]]);
259  }
260  else
261  {
262  // We don't yet handle anything higher order than quadratic...
263  mooseError("Unable to bias node at node(", dir, ")=", node(dir));
264  }
265  }
266  }
267  }
268  }
269 
270  return dynamic_pointer_cast<MeshBase>(mesh);
271 }
GeneratedMeshGenerator.h
GeneratedMeshGenerator::_gauss_lobatto_grid
bool _gauss_lobatto_grid
All of the libmesh build_line/square/cube routines support an option to grade the mesh into the bound...
Definition: GeneratedMeshGenerator.h:48
GeneratedMeshGenerator::_ny
unsigned int & _ny
Definition: GeneratedMeshGenerator.h:38
GeneratedMeshGenerator::_bias_z
Real _bias_z
Definition: GeneratedMeshGenerator.h:55
MathUtils::round
T round(T x)
Definition: MathUtils.h:30
MooseObject::mooseError
void mooseError(Args &&... args) const
Definition: MooseObject.h:141
MooseObject::isParamValid
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:100
GeneratedMeshGenerator::_zmin
Real & _zmin
Definition: GeneratedMeshGenerator.h:41
std::abs
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
MeshGenerator
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:32
MooseEnum
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
InputParameters::addParam
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object.
Definition: InputParameters.h:1198
GeneratedMeshGenerator::_nz
unsigned int & _nz
Definition: GeneratedMeshGenerator.h:38
GeneratedMeshGenerator::_zmax
Real & _zmax
Definition: GeneratedMeshGenerator.h:41
registerMooseObject
registerMooseObject("MooseApp", GeneratedMeshGenerator)
GeneratedMeshGenerator::_bias_x
Real _bias_x
The amount by which to bias the cells in the x,y,z directions.
Definition: GeneratedMeshGenerator.h:55
MeshGenerator::_mesh
std::shared_ptr< MooseMesh > & _mesh
References to the mesh and displaced mesh (currently in the ActionWarehouse)
Definition: MeshGenerator.h:87
InputParameters
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
Definition: InputParameters.h:53
defineLegacyParams
defineLegacyParams(GeneratedMeshGenerator)
GeneratedMeshGenerator::GeneratedMeshGenerator
GeneratedMeshGenerator(const InputParameters &parameters)
Definition: GeneratedMeshGenerator.C:85
GeneratedMeshGenerator::_ymax
Real & _ymax
Definition: GeneratedMeshGenerator.h:41
InputParameters::addClassDescription
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.
Definition: InputParameters.C:70
GeneratedMeshGenerator::_bias_y
Real _bias_y
Definition: GeneratedMeshGenerator.h:55
InputParameters::addRangeCheckedParam
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
Definition: InputParameters.h:1245
MathUtils::pow
T pow(T x, int e)
Definition: MathUtils.h:44
GeneratedMeshGenerator::_dim
MooseEnum _dim
The dimension of the mesh.
Definition: GeneratedMeshGenerator.h:35
GeneratedMeshGenerator
Generates a line, square, or cube mesh with uniformly spaced or biased elements.
Definition: GeneratedMeshGenerator.h:24
GeneratedMeshGenerator::_ymin
Real & _ymin
Definition: GeneratedMeshGenerator.h:41
build_cube
void build_cube(UnstructuredMesh &mesh, const unsigned int nx, unsigned int ny, unsigned int nz, const Real xmin, const Real xmax, const Real ymin, const Real ymax, const Real zmin, const Real zmax, const ElemType type, bool verbose)
Definition: DistributedGeneratedMesh.C:1068
InputParameters::addParamNamesToGroup
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...
Definition: InputParameters.C:590
MeshGenerator::validParams
static InputParameters validParams()
Constructor.
Definition: MeshGenerator.C:17
CastUniquePointer.h
GeneratedMeshGenerator::generate
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
Definition: GeneratedMeshGenerator.C:107
GeneratedMeshGenerator::validParams
static InputParameters validParams()
Definition: GeneratedMeshGenerator.C:29
GeneratedMeshGenerator::_xmin
Real & _xmin
The min/max values for x,y,z component.
Definition: GeneratedMeshGenerator.h:41
InputParameters::addRequiredParam
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...
Definition: InputParameters.h:1176
GeneratedMeshGenerator::_nx
unsigned int & _nx
Number of elements in x, y, z direction.
Definition: GeneratedMeshGenerator.h:38
GeneratedMeshGenerator::_xmax
Real & _xmax
Definition: GeneratedMeshGenerator.h:41
MooseObject::name
virtual const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:70