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 #include "MooseMeshUtils.h"
15 
16 #include "libmesh/distributed_mesh.h"
17 #include "libmesh/elem.h"
18 
19 #include <set>
20 #include <typeinfo>
21 
23 
25 
28 {
30 
31  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
32  params.addParam<SubdomainID>("new_block_id", "The lower dimensional block id to create");
33  params.addParam<SubdomainName>("new_block_name",
34  "The lower dimensional block name to create (optional)");
35  params.addRequiredParam<std::vector<BoundaryName>>(
36  "sidesets", "The sidesets from which to create the new block");
37 
38  params.addClassDescription("Adds lower dimensional elements on the specified sidesets.");
39 
40  return params;
41 }
42 
44  : MeshGenerator(parameters),
45  _input(getMesh("input")),
46  _sideset_names(getParam<std::vector<BoundaryName>>("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  // Generate a new block id if one isn't supplied.
66  SubdomainID new_block_id;
67  if (isParamValid("new_block_id"))
68  new_block_id = getParam<SubdomainID>("new_block_id");
69  else
70  {
71  std::set<SubdomainID> preexisting_subdomain_ids;
72  mesh->subdomain_ids(preexisting_subdomain_ids);
73  if (preexisting_subdomain_ids.empty())
74  new_block_id = 0;
75  else
76  {
77  const auto highest_subdomain_id =
78  *std::max_element(preexisting_subdomain_ids.begin(), preexisting_subdomain_ids.end());
79  mooseAssert(highest_subdomain_id < std::numeric_limits<SubdomainID>::max(),
80  "A SubdomainID with max possible value was found");
81  new_block_id = highest_subdomain_id + 1;
82  }
83  }
84 
85  bool distributed = false;
86  if (typeid(mesh).name() == typeid(std::unique_ptr<DistributedMesh>).name())
87  distributed = true;
88 
89  auto side_list = mesh->get_boundary_info().build_side_list();
90  std::sort(side_list.begin(),
91  side_list.end(),
92  [](std::tuple<dof_id_type, unsigned short int, boundary_id_type> a,
93  std::tuple<dof_id_type, unsigned short int, boundary_id_type> b) {
94  auto a_elem_id = std::get<0>(a);
95  auto b_elem_id = std::get<0>(b);
96  if (a_elem_id == b_elem_id)
97  {
98  auto a_side_id = std::get<1>(a);
99  auto b_side_id = std::get<1>(b);
100  if (a_side_id == b_side_id)
101  return std::get<2>(a) < std::get<2>(b);
102  else
103  return a_side_id < b_side_id;
104  }
105  else
106  return a_elem_id < b_elem_id;
107  });
108 
109  auto sideset_ids = MooseMeshUtils::getBoundaryIDs(*mesh, _sideset_names, true);
110  std::set<boundary_id_type> sidesets(sideset_ids.begin(), sideset_ids.end());
111 
112  std::vector<ElemSideDouble> element_sides_on_boundary;
113  for (const auto & triple : side_list)
114  if (sidesets.count(std::get<2>(triple)))
115  element_sides_on_boundary.push_back(
116  ElemSideDouble(mesh->elem_ptr(std::get<0>(triple)), std::get<1>(triple)));
117 
118  dof_id_type max_elem_id = mesh->max_elem_id();
119  mesh->comm().max(max_elem_id);
120  auto max_elems_to_add = element_sides_on_boundary.size();
121  mesh->comm().max(max_elems_to_add);
122 
123  for (MooseIndex(element_sides_on_boundary) i = 0; i < element_sides_on_boundary.size(); ++i)
124  {
125  Elem * elem = element_sides_on_boundary[i].elem;
126  if (distributed && elem->processor_id() != processor_id())
127  continue;
128 
129  unsigned int side = element_sides_on_boundary[i].side;
130 
131  // Build a non-proxy element from this side.
132  std::unique_ptr<Elem> side_elem(elem->build_side_ptr(side, /*proxy=*/false));
133 
134  // The side will be added with the same processor id as the parent.
135  side_elem->processor_id() = elem->processor_id();
136 
137  // Add subdomain ID
138  side_elem->subdomain_id() = new_block_id;
139 
140  // Also assign the side's interior parent, so it is always
141  // easy to figure out the Elem we came from.
142  side_elem->set_interior_parent(elem);
143 
144  // Add id for distributed
145  if (distributed)
146  side_elem->set_id(max_elem_id + processor_id() * max_elems_to_add + i);
147 
148  // Finally, add the lower-dimensional element to the Mesh.
149  mesh->add_elem(side_elem.release());
150  };
151 
152  // Assign block name, if provided
153  if (isParamValid("new_block_name"))
154  mesh->subdomain_name(new_block_id) = getParam<SubdomainName>("new_block_name");
155 
156  return mesh;
157 }
LowerDBlockFromSidesetGenerator::_sideset_names
const std::vector< BoundaryName > _sideset_names
Definition: LowerDBlockFromSidesetGenerator.h:35
MooseMeshUtils::getBoundaryIDs
std::vector< libMesh::boundary_id_type > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown)
Definition: MooseMeshUtils.C:63
MooseMeshUtils.h
MooseObject::isParamValid
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
Definition: MooseObject.h:100
MeshGenerator
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:32
LowerDBlockFromSidesetGenerator::validParams
static InputParameters validParams()
Definition: LowerDBlockFromSidesetGenerator.C:27
InputParameters::addParam
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.
Definition: InputParameters.h:1198
defineLegacyParams
defineLegacyParams(LowerDBlockFromSidesetGenerator)
LowerDBlockFromSidesetGenerator::generate
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
Definition: LowerDBlockFromSidesetGenerator.C:61
ElemSideDouble::side
unsigned short int side
Definition: LowerDBlockFromSidesetGenerator.C:57
ElemSideDouble::elem
Elem * elem
Definition: LowerDBlockFromSidesetGenerator.C:56
InputParameters
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
Definition: InputParameters.h:53
ElemSideDouble
Definition: LowerDBlockFromSidesetGenerator.C:52
LowerDBlockFromSidesetGenerator
Creates lower-dimensional elements on the specified sidesets.
Definition: LowerDBlockFromSidesetGenerator.h:23
InputParameters.h
InputParameters::addClassDescription
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.
Definition: InputParameters.C:70
registerMooseObject
registerMooseObject("MooseApp", LowerDBlockFromSidesetGenerator)
SubdomainID
subdomain_id_type SubdomainID
Definition: AutomaticMortarGeneration.h:48
std
Definition: TheWarehouse.h:80
MeshGenerator::validParams
static InputParameters validParams()
Constructor.
Definition: MeshGenerator.C:17
LowerDBlockFromSidesetGenerator::LowerDBlockFromSidesetGenerator
LowerDBlockFromSidesetGenerator(const InputParameters &parameters)
Definition: LowerDBlockFromSidesetGenerator.C:43
CastUniquePointer.h
LowerDBlockFromSidesetGenerator.h
MooseTypes.h
LowerDBlockFromSidesetGenerator::_input
std::unique_ptr< MeshBase > & _input
Definition: LowerDBlockFromSidesetGenerator.h:33
InputParameters::addRequiredParam
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...
Definition: InputParameters.h:1176
ElemSideDouble::ElemSideDouble
ElemSideDouble(Elem *elem_in, unsigned short int side_in)
Definition: LowerDBlockFromSidesetGenerator.C:54
MooseObject::name
virtual const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:70