www.mooseframework.org
StackGenerator.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 "StackGenerator.h"
11 #include "CastUniquePointer.h"
12 
13 #include "libmesh/replicated_mesh.h"
14 #include "libmesh/distributed_mesh.h"
15 #include "libmesh/boundary_info.h"
16 #include "libmesh/mesh_modification.h"
17 #include "libmesh/bounding_box.h"
18 #include "libmesh/mesh_tools.h"
19 #include "libmesh/point.h"
20 #include "MooseMeshUtils.h"
21 
22 #include <typeinfo>
23 
25 
28 {
30 
31  MooseEnum dims("2=2 3=3");
32  params.addRequiredParam<MooseEnum>("dim", dims, "The dimension of the mesh to be generated");
33 
34  params.addRequiredParam<std::vector<MeshGeneratorName>>("inputs",
35  "The meshes we want to stitch together");
36 
37  params.addParam<Real>("bottom_height", 0, "The height of the bottom of the final mesh");
38 
39  // y boundary names (2D case)
40  params.addParam<BoundaryName>("top_boundary", "top", "name of the top (y) boundary");
41  params.addParam<BoundaryName>("bottom_boundary", "bottom", "name of the bottom (y) boundary");
42 
43  // z boundary names (3D case)
44  params.addParam<BoundaryName>("front_boundary", "front", "name of the front (z) boundary");
45  params.addParam<BoundaryName>("back_boundary", "back", "name of the back (z) boundary");
46 
47  params.addClassDescription("Use the supplied meshes and stitch them on top of each other");
48 
49  return params;
50 }
51 
53  : MeshGenerator(parameters),
54  _dim(getParam<MooseEnum>("dim")),
55  _mesh_ptrs(getMeshes("inputs")),
56  _input_names(getParam<std::vector<MeshGeneratorName>>("inputs")),
57  _bottom_height(getParam<Real>("bottom_height"))
58 {
59 }
60 
61 std::unique_ptr<MeshBase>
63 {
64  std::unique_ptr<ReplicatedMesh> mesh = dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[0]);
65  if (mesh == nullptr)
66  mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
67  _input_names[0],
68  "is not a ReplicatedMesh.");
69 
70  int dim = static_cast<int>(_dim);
71 
72  if (dim != int(mesh->mesh_dimension()))
73  paramError("dim",
74  "incompatible mesh dimensions: dim=",
75  dim,
76  " and first mesh dimension is ",
77  mesh->mesh_dimension());
78 
79  // Reserve spaces for the other meshes (no need to store the first one another time)
80  _meshes.reserve(_input_names.size() - 1);
81 
82  // Read in all of the other meshes
83  for (MooseIndex(_input_names) i = 1; i < _input_names.size(); ++i)
84  _meshes.push_back(dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[i]));
85 
86  // Check that the casts didn't fail, and that the dimensions match
87  for (MooseIndex(_meshes) i = 0; i < _meshes.size(); ++i)
88  {
89  if (_meshes[i] == nullptr)
90  mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
91  _input_names[i + 1],
92  "is not a ReplicatedMesh.");
93  if (static_cast<int>(_meshes[i]->mesh_dimension()) != dim)
94  mooseError("Mesh from MeshGenerator : ", _input_names[i + 1], " is not in ", _dim, "D.");
95  }
96 
97  // Getting the boundaries provided by the user
98  std::vector<BoundaryName> boundary_names = {getParam<BoundaryName>("top_boundary"),
99  getParam<BoundaryName>("bottom_boundary")};
100  if (dim == 3)
101  boundary_names = {getParam<BoundaryName>("front_boundary"),
102  getParam<BoundaryName>("back_boundary")};
103 
104  std::vector<boundary_id_type> ids =
105  MooseMeshUtils::getBoundaryIDs(*_meshes[0], boundary_names, true);
106 
107  mooseAssert(ids.size() == boundary_names.size(),
108  "Unexpected number of ids returned for MooseMeshUtils::getBoundaryIDs");
109 
110  boundary_id_type first = ids[0], second = ids[1];
111 
112  // Getting the width of each mesh
113  std::vector<Real> heights;
114  heights.push_back(computeWidth(*mesh, _dim) + _bottom_height);
115  for (MooseIndex(_meshes) i = 0; i < _meshes.size(); ++i)
116  heights.push_back(computeWidth(*_meshes[i], _dim) + *heights.rbegin());
117 
118  // Move the first mesh at the provided height
119  switch (_dim)
120  {
121  case 2:
122  MeshTools::Modification::translate(*mesh, 0, _bottom_height, 0);
123  break;
124  case 3:
125  MeshTools::Modification::translate(*mesh, 0, 0, _bottom_height);
126  break;
127  }
128 
129  // Move all of the other meshes in the right spots then stitch them one by one to the first one
130  for (MooseIndex(_meshes) i = 0; i < _meshes.size(); ++i)
131  {
132  switch (_dim)
133  {
134  case 2:
135  MeshTools::Modification::translate(*_meshes[i], 0, heights[i], 0);
136  break;
137  case 3:
138  MeshTools::Modification::translate(*_meshes[i], 0, 0, heights[i]);
139  break;
140  }
141  mesh->stitch_meshes(
142  *_meshes[i], first, second, TOLERANCE, /*clear_stitched_boundary_ids=*/true);
143  }
144 
145  return dynamic_pointer_cast<MeshBase>(mesh);
146 }
147 
148 Real
149 StackGenerator::computeWidth(const MeshBase & mesh, const int & dim)
150 {
151  BoundingBox bbox = MeshTools::create_bounding_box(mesh);
152  return bbox.max()(dim - 1) - bbox.min()(dim - 1);
153 }
const std::vector< MeshGeneratorName > & _input_names
The meshgenerators to read.
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
StackGenerator(const InputParameters &parameters)
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
Definition: Moose.h:148
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.
registerMooseObject("MooseApp", StackGenerator)
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...
const std::vector< std::unique_ptr< MeshBase > * > _mesh_ptrs
int8_t boundary_id_type
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
std::vector< std::unique_ptr< ReplicatedMesh > > _meshes
The meshes to be stitched together.
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
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 ...
const Real _bottom_height
Height (z) of the bottom of the final mesh.
static InputParameters validParams()
Definition: MeshGenerator.C:23
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
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...
Real computeWidth(const MeshBase &mesh, const int &dim)
static InputParameters validParams()
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:32
const MooseEnum _dim
The dimension of the mesh.
Take several 3D meshes and stitch them on top of each other like a stack.