www.mooseframework.org
PatternedMeshGenerator.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 "PatternedMeshGenerator.h"
11 
12 #include "CastUniquePointer.h"
13 
14 #include "libmesh/replicated_mesh.h"
15 #include "libmesh/distributed_mesh.h"
16 #include "libmesh/boundary_info.h"
17 #include "libmesh/mesh_modification.h"
18 #include "libmesh/mesh_tools.h"
19 #include "MooseMeshUtils.h"
20 
22 
23 template <>
26 {
28 
29  params.addRequiredParam<std::vector<MeshGeneratorName>>("inputs", "The input MeshGenerators.");
30  params.addRangeCheckedParam<Real>(
31  "x_width", 0, "x_width>=0", "The tile width in the x direction");
32  params.addRangeCheckedParam<Real>(
33  "y_width", 0, "y_width>=0", "The tile width in the y direction");
34  params.addRangeCheckedParam<Real>(
35  "z_width", 0, "z_width>=0", "The tile width in the z direction");
36 
37  // Boundaries : user has to provide id or name for each boundary
38 
39  // x boundary names
40  params.addParam<BoundaryName>("left_boundary", "left", "name of the left (x) boundary");
41  params.addParam<BoundaryName>("right_boundary", "right", "name of the right (x) boundary");
42 
43  // y boundary names
44  params.addParam<BoundaryName>("top_boundary", "top", "name of the top (y) boundary");
45  params.addParam<BoundaryName>("bottom_boundary", "bottom", "name of the bottom (y) boundary");
46 
47  params.addRequiredParam<std::vector<std::vector<unsigned int>>>(
48  "pattern", "A double-indexed array starting with the upper-left corner");
49 
50  params.addClassDescription("Creates a 2D mesh from a specified set of unique 'tiles' meshes and "
51  "a two-dimensional pattern.");
52 
53  return params;
54 }
55 
57  : MeshGenerator(parameters),
58  _input_names(getParam<std::vector<MeshGeneratorName>>("inputs")),
59  _pattern(getParam<std::vector<std::vector<unsigned int>>>("pattern")),
60  _x_width(getParam<Real>("x_width")),
61  _y_width(getParam<Real>("y_width")),
62  _z_width(getParam<Real>("z_width"))
63 {
64  _mesh_ptrs.reserve(_input_names.size());
65  for (auto & input_name : _input_names)
66  _mesh_ptrs.push_back(&getMeshByName(input_name));
67 }
68 
69 std::unique_ptr<MeshBase>
71 {
72  // Reserve spaces for all the meshes
73  _meshes.reserve(_input_names.size());
74 
75  // Read in all of the meshes
76  for (MooseIndex(_input_names) i = 0; i < _input_names.size(); ++i)
77  {
78  _meshes.push_back(dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[i]));
79  }
80 
81  // Data structure that holds each row
82  _row_meshes.resize(_pattern.size());
83 
84  // Getting the boundaries provided by the user
85  std::vector<BoundaryName> boundary_names = {getParam<BoundaryName>("left_boundary"),
86  getParam<BoundaryName>("right_boundary"),
87  getParam<BoundaryName>("top_boundary"),
88  getParam<BoundaryName>("bottom_boundary")};
89 
90  std::vector<boundary_id_type> ids =
91  MooseMeshUtils::getBoundaryIDs(*_meshes[0], boundary_names, true);
92 
93  mooseAssert(ids.size() == boundary_names.size(),
94  "Unexpected number of ids returned for MooseMeshUtils::getBoundaryIDs");
95 
96  boundary_id_type left = ids[0], right = ids[1], top = ids[2], bottom = ids[3];
97 
98  // Check if all the boundaries have been initialized
99  if (left == -123)
100  mooseError("The left boundary has not been initialized properly.");
101  if (right == -123)
102  mooseError("The right boundary has not been initialized properly.");
103  if (top == -123)
104  mooseError("The top boundary has not been initialized properly.");
105  if (bottom == -123)
106  mooseError("The bottom boundary has not been initialized properly.");
107 
108  // Check if the user has provided the x, y and z widths.
109  // If not (their value is 0 by default), compute them
110  auto bbox = MeshTools::create_bounding_box(*_meshes[0]);
111  if (_x_width == 0)
112  _x_width = bbox.max()(0) - bbox.min()(0);
113  if (_y_width == 0)
114  _y_width = bbox.max()(1) - bbox.min()(1);
115  if (_z_width == 0)
116  _z_width = bbox.max()(2) - bbox.min()(2);
117 
118  // Build each row mesh
119  for (MooseIndex(_pattern) i = 0; i < _pattern.size(); ++i)
120  for (MooseIndex(_pattern[i]) j = 0; j < _pattern[i].size(); ++j)
121  {
122  Real deltax = j * _x_width, deltay = i * _y_width;
123 
124  // If this is the first cell of the row initialize the row mesh
125  if (j == 0)
126  {
127  //_row_meshes[i] = _mesh_ptrs[_pattern[i][j]]->clone();
128  auto clone = _meshes[_pattern[i][j]]->clone();
129  _row_meshes[i] = dynamic_pointer_cast<ReplicatedMesh>(clone);
130 
131  MeshTools::Modification::translate(*_row_meshes[i], deltax, -deltay, 0);
132 
133  continue;
134  }
135 
136  ReplicatedMesh & cell_mesh = *_meshes[_pattern[i][j]];
137 
138  // Move the mesh into the right spot. -i because we are starting at the top
139  MeshTools::Modification::translate(cell_mesh, deltax, -deltay, 0);
140 
141  _row_meshes[i]->stitch_meshes(cell_mesh,
142  right,
143  left,
144  TOLERANCE,
145  /*clear_stitched_boundary_ids=*/true);
146 
147  // Undo the translation
148  MeshTools::Modification::translate(cell_mesh, -deltax, deltay, 0);
149  }
150 
151  // Now stitch together the rows
152  // We're going to stitch them all to row 0 (which is the real mesh)
153  for (MooseIndex(_pattern) i = 1; i < _pattern.size(); i++)
154  _row_meshes[0]->stitch_meshes(
155  *_row_meshes[i], bottom, top, TOLERANCE, /*clear_stitched_boundary_ids=*/true);
156 
157  return dynamic_pointer_cast<MeshBase>(_row_meshes[0]);
158 }
Reads one or more 2D mesh files and stitches them together based on a provided two-dimensional patter...
PatternedMeshGenerator(const InputParameters &parameters)
std::vector< std::unique_ptr< ReplicatedMesh > > _meshes
const std::vector< std::vector< unsigned int > > & _pattern
registerMooseObject("MooseApp", PatternedMeshGenerator)
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.
std::unique_ptr< MeshBase > & getMeshByName(const MeshGeneratorName &input_mesh_generator_parameter_name)
Takes the name of another MeshGenerator directly.
Definition: MeshGenerator.C:47
std::vector< std::unique_ptr< ReplicatedMesh > > _row_meshes
void mooseError(Args &&... args) const
Definition: MooseObject.h:147
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...
InputParameters validParams< PatternedMeshGenerator >()
std::vector< std::unique_ptr< MeshBase > * > _mesh_ptrs
std::vector< libMesh::boundary_id_type > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown)
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
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 option parameter and a documentation string to the InputParameters object...
void addRangeCheckedParam(const std::string &name, const T &value, const std::string &parsed_function, const std::string &doc_string)
InputParameters validParams< MeshGenerator >()
Definition: MeshGenerator.C:16
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:30
const std::vector< MeshGeneratorName > & _input_names
The mesh generators to read.