https://mooseframework.inl.gov
MeshCollectionGenerator.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 
11 
12 #include "CastUniquePointer.h"
13 #include "MooseUtils.h"
14 
15 #include "libmesh/replicated_mesh.h"
16 #include "libmesh/unstructured_mesh.h"
17 
19 
22 {
24  params.addClassDescription("Collects multiple meshes into a single (unconnected) mesh.");
25  params.addRequiredParam<std::vector<MeshGeneratorName>>("inputs", "The input MeshGenerators.");
26  return params;
27 }
28 
30  : MeshGenerator(parameters),
31  _input_names(getParam<std::vector<MeshGeneratorName>>("inputs")),
32  _meshes(getMeshes("inputs"))
33 {
34  // error check
35  if (_input_names.empty())
36  paramError("input_names", "You need to specify at least one MeshGenerator as an input.");
37 }
38 
39 std::unique_ptr<MeshBase>
41 {
42  // merge all meshes into the first one
43  auto mesh = dynamic_pointer_cast<UnstructuredMesh>(std::move(*_meshes[0]));
44  if (!mesh)
45  paramError("inputs", _input_names[0], " is not a valid unstructured mesh");
46 
47  // Read in all of the other meshes
48  for (MooseIndex(_meshes) i = 1; i < _meshes.size(); ++i)
49  {
50  auto other_mesh = dynamic_pointer_cast<UnstructuredMesh>(std::move(*_meshes[i]));
51  if (!other_mesh)
52  paramError("inputs", _input_names[i], " is not a valid unstructured mesh");
53 
54  dof_id_type node_delta = mesh->max_node_id();
55  dof_id_type elem_delta = mesh->max_elem_id();
56 
57  unique_id_type unique_delta =
58 #ifdef LIBMESH_ENABLE_UNIQUE_ID
59  mesh->parallel_max_unique_id();
60 #else
61  0;
62 #endif
63 
64  // Copy mesh data over from the other mesh
65  mesh->copy_nodes_and_elements(*other_mesh,
66  /*skip_find_neighbors = */ false,
67  elem_delta,
68  node_delta,
69  unique_delta);
70 
71  // Copy BoundaryInfo from other_mesh too. We do this via the
72  // list APIs rather than element-by-element for speed.
73  BoundaryInfo & boundary = mesh->get_boundary_info();
74  const BoundaryInfo & other_boundary = other_mesh->get_boundary_info();
75 
76  for (const auto & t : other_boundary.build_node_list())
77  boundary.add_node(std::get<0>(t) + node_delta, std::get<1>(t));
78 
79  for (const auto & t : other_boundary.build_side_list())
80  boundary.add_side(std::get<0>(t) + elem_delta, std::get<1>(t), std::get<2>(t));
81 
82  for (const auto & t : other_boundary.build_edge_list())
83  boundary.add_edge(std::get<0>(t) + elem_delta, std::get<1>(t), std::get<2>(t));
84 
85  for (const auto & t : other_boundary.build_shellface_list())
86  boundary.add_shellface(std::get<0>(t) + elem_delta, std::get<1>(t), std::get<2>(t));
87 
88  const auto & boundary_ids = boundary.get_boundary_ids();
89  const auto & other_boundary_ids = other_boundary.get_boundary_ids();
90  for (auto id : other_boundary_ids)
91  {
92  // check if the boundary id already exists with a different name
93  if (boundary_ids.count(id))
94  {
95  if (boundary.get_sideset_name(id) != "" &&
96  boundary.get_sideset_name(id) != other_boundary.get_sideset_name(id))
97  mooseError("A sideset with id ",
98  id,
99  " exists but has different names in the merged meshes ('",
100  boundary.get_sideset_name(id),
101  "' vs.'",
102  other_boundary.get_sideset_name(id),
103  "').");
104 
105  boundary.sideset_name(id) = other_boundary.get_sideset_name(id);
106 
107  if (boundary.get_nodeset_name(id) != "" &&
108  boundary.get_nodeset_name(id) != other_boundary.get_nodeset_name(id))
109  mooseError("A nodeset with id ",
110  id,
111  " exists but has different names in the merged meshes ('",
112  boundary.get_nodeset_name(id),
113  "' vs.'",
114  other_boundary.get_nodeset_name(id),
115  "').");
116 
117  boundary.nodeset_name(id) = other_boundary.get_nodeset_name(id);
118  }
119  }
120  }
121 
122  mesh->set_isnt_prepared();
123  return dynamic_pointer_cast<MeshBase>(mesh);
124 }
const std::vector< std::unique_ptr< MeshBase > * > _meshes
MeshBase & mesh
std::unique_ptr< MeshBase > generate() override
Generate / modify the 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.
registerMooseObject("MooseApp", MeshCollectionGenerator)
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...
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 ...
static InputParameters validParams()
Definition: MeshGenerator.C:23
static InputParameters validParams()
MeshCollectionGenerator(const InputParameters &parameters)
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...
Collects multiple meshes into a single (unconnected) mesh.
const std::vector< MeshGeneratorName > & _input_names
The mesh generators to read.
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:32
uint8_t unique_id_type
uint8_t dof_id_type