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 
26 template <>
29 {
31 
32  MooseEnum dims("2=2 3=3");
33  params.addRequiredParam<MooseEnum>("dim", dims, "The dimension of the mesh to be generated");
34 
35  params.addRequiredParam<std::vector<MeshGeneratorName>>("inputs",
36  "The meshes we want to stitch together");
37 
38  params.addParam<Real>("bottom_height", 0, "The height of the bottom of the final mesh");
39 
40  // y boundary names (2D case)
41  params.addParam<BoundaryName>("top_boundary", "top", "name of the top (y) boundary");
42  params.addParam<BoundaryName>("bottom_boundary", "bottom", "name of the bottom (y) boundary");
43 
44  // z boundary names (3D case)
45  params.addParam<BoundaryName>("front_boundary", "front", "name of the front (z) boundary");
46  params.addParam<BoundaryName>("back_boundary", "back", "name of the back (z) boundary");
47 
48  params.addClassDescription("Use the supplied meshes and stitch them on top of each other");
49 
50  return params;
51 }
52 
54  : MeshGenerator(parameters),
55  _dim(getParam<MooseEnum>("dim")),
56  _input_names(getParam<std::vector<MeshGeneratorName>>("inputs")),
57  _bottom_height(getParam<Real>("bottom_height"))
58 {
59  // Grab the input meshes
60  _mesh_ptrs.reserve(_input_names.size());
61  for (auto & input_name : _input_names)
62  _mesh_ptrs.push_back(&getMeshByName(input_name));
63 }
64 
65 std::unique_ptr<MeshBase>
67 {
68  std::unique_ptr<ReplicatedMesh> mesh = dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[0]);
69  if (mesh == nullptr)
70  mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
71  _input_names[0],
72  "is not a ReplicatedMesh.");
73 
74  int dim = static_cast<int>(_dim);
75 
76  if (dim != int(mesh->mesh_dimension()))
77  paramError("dim",
78  "incompatible mesh dimensions: dim=",
79  dim,
80  " and first mesh dimension is ",
81  mesh->mesh_dimension());
82 
83  // Reserve spaces for the other meshes (no need to store the first one another time)
84  _meshes.reserve(_input_names.size() - 1);
85 
86  // Read in all of the other meshes
87  for (MooseIndex(_input_names) i = 1; i < _input_names.size(); ++i)
88  _meshes.push_back(dynamic_pointer_cast<ReplicatedMesh>(*_mesh_ptrs[i]));
89 
90  // Check that the casts didn't fail, and that the dimensions match
91  for (MooseIndex(_meshes) i = 0; i < _meshes.size(); ++i)
92  {
93  if (_meshes[i] == nullptr)
94  mooseError("StackGenerator only works with ReplicatedMesh : mesh from Meshgenerator ",
95  _input_names[i + 1],
96  "is not a ReplicatedMesh.");
97  if (static_cast<int>(_meshes[i]->mesh_dimension()) != dim)
98  mooseError("Mesh from MeshGenerator : ", _input_names[i + 1], " is not in ", _dim, "D.");
99  }
100 
101  // Getting the boundaries provided by the user
102  std::vector<BoundaryName> boundary_names = {getParam<BoundaryName>("top_boundary"),
103  getParam<BoundaryName>("bottom_boundary")};
104  if (dim == 3)
105  boundary_names = {getParam<BoundaryName>("front_boundary"),
106  getParam<BoundaryName>("back_boundary")};
107 
108  std::vector<boundary_id_type> ids =
109  MooseMeshUtils::getBoundaryIDs(*_meshes[0], boundary_names, true);
110 
111  mooseAssert(ids.size() == boundary_names.size(),
112  "Unexpected number of ids returned for MooseMeshUtils::getBoundaryIDs");
113 
114  boundary_id_type first = ids[0], second = ids[1];
115 
116  // Getting the width of each mesh
117  std::vector<Real> heights;
118  heights.push_back(computeWidth(*mesh, _dim) + _bottom_height);
119  for (MooseIndex(_meshes) i = 0; i < _meshes.size(); ++i)
120  heights.push_back(computeWidth(*_meshes[i], _dim) + *heights.rbegin());
121 
122  // Move the first mesh at the provided height
123  switch (_dim)
124  {
125  case 2:
126  MeshTools::Modification::translate(*mesh, 0, _bottom_height, 0);
127  break;
128  case 3:
129  MeshTools::Modification::translate(*mesh, 0, 0, _bottom_height);
130  break;
131  }
132 
133  // Move all of the other meshes in the right spots then stitch them one by one to the first one
134  for (MooseIndex(_meshes) i = 0; i < _meshes.size(); ++i)
135  {
136  switch (_dim)
137  {
138  case 2:
139  MeshTools::Modification::translate(*_meshes[i], 0, heights[i], 0);
140  break;
141  case 3:
142  MeshTools::Modification::translate(*_meshes[i], 0, 0, heights[i]);
143  break;
144  }
145  mesh->stitch_meshes(
146  *_meshes[i], first, second, TOLERANCE, /*clear_stitched_boundary_ids=*/true);
147  }
148 
149  return dynamic_pointer_cast<MeshBase>(mesh);
150 }
151 
152 Real
153 StackGenerator::computeWidth(const MeshBase & mesh, const int & dim)
154 {
155  BoundingBox bbox = MeshTools::create_bounding_box(mesh);
156  return bbox.max()(dim - 1) - bbox.min()(dim - 1);
157 }
const std::vector< MeshGeneratorName > & _input_names
The meshgenerators to read.
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
StackGenerator(const InputParameters &parameters)
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
void mooseError(Args &&... args) const
Definition: MooseObject.h:147
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...
MooseEnum _dim
The dimension of the mesh.
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
const Real _bottom_height
Height (z) of the bottom of the final mesh.
void paramError(const std::string &param, Args... args)
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition: MooseObject.h:108
std::vector< libMesh::boundary_id_type > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown)
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)
InputParameters validParams< MeshGenerator >()
Definition: MeshGenerator.C:16
std::vector< std::unique_ptr< MeshBase > * > _mesh_ptrs
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:30
Take several 3D meshes and stitch them on top of each other like a stack.
InputParameters validParams< StackGenerator >()