www.mooseframework.org
BreakBoundaryOnSubdomainGenerator.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 "CastUniquePointer.h"
12 
13 #include "MooseUtils.h"
14 #include "MooseMeshUtils.h"
15 
16 #include "libmesh/elem.h"
17 
19 
20 template <>
23 {
25 
26  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
27  params.addClassDescription("Break boundaries based on the subdomains to which their sides are "
28  "attached. Naming convention for the new boundaries will be the old "
29  "boundary name plus \"_to_\" plus the subdomain name");
30  params.addParam<std::vector<BoundaryName>>(
31  "boundaries", "Boundaries to be broken. Default means to break all boundaries");
32 
33  return params;
34 }
35 
37  const InputParameters & parameters)
38  : MeshGenerator(parameters), _input(getMesh("input"))
39 {
40 }
41 
42 std::unique_ptr<MeshBase>
44 {
45  // get the mesh and boundary info
46  std::unique_ptr<MeshBase> mesh = std::move(_input);
47  auto & boundary_info = mesh->get_boundary_info();
48 
49  // get IDs of all boundaries to be broken
50  std::set<boundary_id_type> breaking_boundary_ids;
51  if (isParamValid("boundaries"))
52  {
53  auto & boundary_names = getParam<std::vector<BoundaryName>>("boundaries");
54  for (auto & boundary_name : boundary_names)
55  breaking_boundary_ids.insert(boundary_info.get_id_by_name(boundary_name));
56  }
57  else
58  {
59  breaking_boundary_ids = boundary_info.get_boundary_ids();
60 
61  // We might be on a distributed mesh with remote boundary ids
62  if (!mesh->is_replicated())
63  this->comm().set_union(breaking_boundary_ids);
64  }
65 
66  // create a list of new boundary names
67  std::set<std::string> new_boundary_name_set;
68  std::vector<boundary_id_type> side_boundary_ids;
69  for (const auto & elem : mesh->active_element_ptr_range())
70  {
71  auto subdomain_id = elem->subdomain_id();
72  auto subdomain_name = mesh->subdomain_name(subdomain_id);
73  if (subdomain_name == "")
74  subdomain_name = std::to_string(subdomain_id);
75  for (unsigned int side = 0; side < elem->n_sides(); ++side)
76  {
77  boundary_info.boundary_ids(elem, side, side_boundary_ids);
78  for (auto boundary_id : side_boundary_ids)
79  if (breaking_boundary_ids.count(boundary_id) > 0)
80  new_boundary_name_set.emplace(boundary_info.sideset_name(boundary_id) + "_to_" +
81  subdomain_name);
82  }
83  }
84 
85  // We might be on a distributed mesh with remote elements that had
86  // new boundary ids added
87  if (!mesh->is_replicated())
88  this->comm().set_union(new_boundary_name_set);
89 
90  // assign boundary IDs to the boundaries to be added
91  std::vector<BoundaryName> new_boundary_names(new_boundary_name_set.begin(),
92  new_boundary_name_set.end());
93  auto new_boundary_ids = MooseMeshUtils::getBoundaryIDs(*mesh, new_boundary_names, true);
94 
95  // assign boundary names to the new boundaries
96  mooseAssert(new_boundary_ids.size() == new_boundary_names.size(),
97  "sizes of boundary names and boundary IDs mismatch");
98  for (MooseIndex(new_boundary_ids) i = 0; i < new_boundary_ids.size(); ++i)
99  {
100  boundary_info.sideset_name(new_boundary_ids[i]) = new_boundary_names[i];
101  boundary_info.nodeset_name(new_boundary_ids[i]) = new_boundary_names[i];
102  }
103 
104  // add sides into the side sets
105  for (const auto & elem : mesh->active_element_ptr_range())
106  {
107  auto subdomain_id = elem->subdomain_id();
108  auto subdomain_name = mesh->subdomain_name(subdomain_id);
109  if (subdomain_name == "")
110  subdomain_name = std::to_string(subdomain_id);
111  for (MooseIndex(elem->n_sides()) side = 0; side < elem->n_sides(); ++side)
112  {
113  std::vector<boundary_id_type> side_boundary_ids;
114  boundary_info.boundary_ids(elem, side, side_boundary_ids);
115  for (auto boundary_id : side_boundary_ids)
116  {
117  if (breaking_boundary_ids.count(boundary_id) > 0)
118  {
119  BoundaryName bname = boundary_info.sideset_name(boundary_id) + "_to_" + subdomain_name;
120  auto bid = boundary_info.get_id_by_name(bname);
121  boundary_info.add_side(elem, side, bid);
122  }
123  }
124  }
125  }
126 
127  return dynamic_pointer_cast<MeshBase>(mesh);
128 }
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
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.
InputParameters validParams< BreakBoundaryOnSubdomainGenerator >()
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...
BreakBoundaryOnSubdomainGenerator(const InputParameters &parameters)
std::vector< libMesh::boundary_id_type > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown)
MPI_Comm comm
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...
registerMooseObject("MooseApp", BreakBoundaryOnSubdomainGenerator)
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