www.mooseframework.org
LowerDBlockFromSidesetGenerator.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 
11 #include "InputParameters.h"
12 #include "MooseTypes.h"
13 #include "CastUniquePointer.h"
14 
15 #include "libmesh/distributed_mesh.h"
16 #include "libmesh/elem.h"
17 
18 #include <set>
19 #include <typeinfo>
20 
22 
23 template <>
26 {
28 
29  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
30  params.addRequiredParam<subdomain_id_type>("new_block_id",
31  "The lower dimensional block id to create");
32  params.addParam<SubdomainName>("new_block_name",
33  "The lower dimensional block name to create (optional)");
34  params.addRequiredParam<std::vector<boundary_id_type>>(
35  "sidesets", "The sidesets from which to create the new block");
36 
37  params.addClassDescription("Adds lower dimensional elements on the specified sidesets.");
38 
39  return params;
40 }
41 
43  : MeshGenerator(parameters),
44  _input(getMesh("input")),
45  _new_block_id(getParam<subdomain_id_type>("new_block_id")),
46  _sidesets(getParam<std::vector<boundary_id_type>>("sidesets"))
47 {
48 }
49 
50 // Used to temporarily store information about which lower-dimensional
51 // sides to add and what subdomain id to use for the added sides.
53 {
54  ElemSideDouble(Elem * elem_in, unsigned short int side_in) : elem(elem_in), side(side_in) {}
55 
56  Elem * elem;
57  unsigned short int side;
58 };
59 
60 std::unique_ptr<MeshBase>
62 {
63  std::unique_ptr<MeshBase> mesh = std::move(_input);
64 
65  bool distributed = false;
66  if (typeid(mesh).name() == typeid(std::unique_ptr<DistributedMesh>).name())
67  distributed = true;
68 
69  auto side_list = mesh->get_boundary_info().build_side_list();
70  std::sort(side_list.begin(),
71  side_list.end(),
72  [](std::tuple<dof_id_type, unsigned short int, boundary_id_type> a,
73  std::tuple<dof_id_type, unsigned short int, boundary_id_type> b) {
74  auto a_elem_id = std::get<0>(a);
75  auto b_elem_id = std::get<0>(b);
76  if (a_elem_id == b_elem_id)
77  {
78  auto a_side_id = std::get<1>(a);
79  auto b_side_id = std::get<1>(b);
80  if (a_side_id == b_side_id)
81  return std::get<2>(a) < std::get<2>(b);
82  else
83  return a_side_id < b_side_id;
84  }
85  else
86  return a_elem_id < b_elem_id;
87  });
88 
89  std::set<boundary_id_type> sidesets(_sidesets.begin(), _sidesets.end());
90  std::vector<ElemSideDouble> element_sides_on_boundary;
91  for (const auto & triple : side_list)
92  if (sidesets.count(std::get<2>(triple)))
93  element_sides_on_boundary.push_back(
94  ElemSideDouble(mesh->elem_ptr(std::get<0>(triple)), std::get<1>(triple)));
95 
96  dof_id_type max_elem_id = mesh->max_elem_id();
97  mesh->comm().max(max_elem_id);
98  auto max_elems_to_add = element_sides_on_boundary.size();
99  mesh->comm().max(max_elems_to_add);
100 
101  for (MooseIndex(element_sides_on_boundary) i = 0; i < element_sides_on_boundary.size(); ++i)
102  {
103  Elem * elem = element_sides_on_boundary[i].elem;
104  if (distributed && elem->processor_id() != processor_id())
105  continue;
106 
107  unsigned int side = element_sides_on_boundary[i].side;
108 
109  // Build a non-proxy element from this side.
110  std::unique_ptr<Elem> side_elem(elem->build_side_ptr(side, /*proxy=*/false));
111 
112  // The side will be added with the same processor id as the parent.
113  side_elem->processor_id() = elem->processor_id();
114 
115  // Add subdomain ID
116  side_elem->subdomain_id() = _new_block_id;
117 
118  // Also assign the side's interior parent, so it is always
119  // easy to figure out the Elem we came from.
120  side_elem->set_interior_parent(elem);
121 
122  // Add id for distributed
123  if (distributed)
124  side_elem->set_id(max_elem_id + processor_id() * max_elems_to_add + i);
125 
126  // Finally, add the lower-dimensional element to the Mesh.
127  mesh->add_elem(side_elem.release());
128  };
129 
130  // Assign block name, if provided
131  if (isParamValid("new_block_name"))
132  mesh->subdomain_name(_new_block_id) = getParam<SubdomainName>("new_block_name");
133 
134  return dynamic_pointer_cast<MeshBase>(mesh);
135 }
const subdomain_id_type _new_block_id
The subdomain ID of the new lower dimensional block.
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.
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...
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
registerMooseObject("MooseApp", LowerDBlockFromSidesetGenerator)
LowerDBlockFromSidesetGenerator(const InputParameters &parameters)
InputParameters validParams< LowerDBlockFromSidesetGenerator >()
ElemSideDouble(Elem *elem_in, unsigned short int side_in)
std::vector< boundary_id_type > _sidesets
The sidesets on which to create the lower dimensional elements.
Creates lower-dimensional elements on the specified sidesets.
const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:59
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...
InputParameters validParams< MeshGenerator >()
Definition: MeshGenerator.C:16
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:89
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:30