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 
22 {
24 
25  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
26  params.addClassDescription("Break boundaries based on the subdomains to which their sides are "
27  "attached. Naming convention for the new boundaries will be the old "
28  "boundary name plus \"_to_\" plus the subdomain name");
29  params.addParam<std::vector<BoundaryName>>(
30  "boundaries", "Boundaries to be broken. Default means to break all boundaries");
31 
32  return params;
33 }
34 
36  const InputParameters & parameters)
37  : MeshGenerator(parameters), _input(getMesh("input"))
38 {
39 }
40 
41 std::unique_ptr<MeshBase>
43 {
44  // get the mesh and boundary info
45  std::unique_ptr<MeshBase> mesh = std::move(_input);
46  auto & boundary_info = mesh->get_boundary_info();
47 
48  // get IDs of all boundaries to be broken
49  std::set<boundary_id_type> breaking_boundary_ids;
50  if (isParamValid("boundaries"))
51  {
52  auto & boundary_names = getParam<std::vector<BoundaryName>>("boundaries");
53  for (auto & boundary_name : boundary_names)
54  {
55  // check that the boundary exists in the mesh
56  if (!MooseMeshUtils::hasBoundaryName(*mesh, boundary_name))
57  paramError("boundaries", "The boundary '", boundary_name, "' was not found in the mesh");
58 
59  breaking_boundary_ids.insert(boundary_info.get_id_by_name(boundary_name));
60  }
61  }
62  else
63  {
64  breaking_boundary_ids = boundary_info.get_boundary_ids();
65 
66  // We might be on a distributed mesh with remote boundary ids
67  if (!mesh->is_replicated())
68  this->comm().set_union(breaking_boundary_ids);
69  }
70 
71  // create a list of new boundary names
72  std::set<std::string> new_boundary_name_set;
73  std::vector<boundary_id_type> side_boundary_ids;
74  for (const auto & elem : mesh->active_element_ptr_range())
75  {
76  auto subdomain_id = elem->subdomain_id();
77  auto subdomain_name = mesh->subdomain_name(subdomain_id);
78  if (subdomain_name == "")
79  subdomain_name = std::to_string(subdomain_id);
80  for (unsigned int side = 0; side < elem->n_sides(); ++side)
81  {
82  boundary_info.boundary_ids(elem, side, side_boundary_ids);
83  for (auto boundary_id : side_boundary_ids)
84  if (breaking_boundary_ids.count(boundary_id) > 0)
85  new_boundary_name_set.emplace(boundary_info.sideset_name(boundary_id) + "_to_" +
86  subdomain_name);
87  }
88  }
89 
90  // We might be on a distributed mesh with remote elements that had
91  // new boundary ids added
92  if (!mesh->is_replicated())
93  this->comm().set_union(new_boundary_name_set);
94 
95  // assign boundary IDs to the boundaries to be added
96  std::vector<BoundaryName> new_boundary_names(new_boundary_name_set.begin(),
97  new_boundary_name_set.end());
98  auto new_boundary_ids = MooseMeshUtils::getBoundaryIDs(*mesh, new_boundary_names, true);
99 
100  // assign boundary names to the new boundaries
101  mooseAssert(new_boundary_ids.size() == new_boundary_names.size(),
102  "sizes of boundary names and boundary IDs mismatch");
103  for (MooseIndex(new_boundary_ids) i = 0; i < new_boundary_ids.size(); ++i)
104  {
105  boundary_info.sideset_name(new_boundary_ids[i]) = new_boundary_names[i];
106  boundary_info.nodeset_name(new_boundary_ids[i]) = new_boundary_names[i];
107  }
108 
109  // add sides into the side sets
110  for (const auto & elem : mesh->active_element_ptr_range())
111  {
112  auto subdomain_id = elem->subdomain_id();
113  auto subdomain_name = mesh->subdomain_name(subdomain_id);
114  if (subdomain_name == "")
115  subdomain_name = std::to_string(subdomain_id);
116  for (MooseIndex(elem->n_sides()) side = 0; side < elem->n_sides(); ++side)
117  {
118  std::vector<boundary_id_type> side_boundary_ids;
119  boundary_info.boundary_ids(elem, side, side_boundary_ids);
120  for (auto boundary_id : side_boundary_ids)
121  {
122  if (breaking_boundary_ids.count(boundary_id) > 0)
123  {
124  BoundaryName bname = boundary_info.sideset_name(boundary_id) + "_to_" + subdomain_name;
125  auto bid = boundary_info.get_id_by_name(bname);
126  boundary_info.add_side(elem, side, bid);
127  }
128  }
129  }
130  }
131 
132  mesh->set_isnt_prepared();
133 
134  return dynamic_pointer_cast<MeshBase>(mesh);
135 }
bool hasBoundaryName(const MeshBase &input_mesh, const BoundaryName &name)
Whether a particular boundary name exists in the mesh.
MeshBase & mesh
std::unique_ptr< MeshBase > & _input
the input mesh to be modified
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.
const Parallel::Communicator & comm() const
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...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
BreakBoundaryOnSubdomainGenerator(const InputParameters &parameters)
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
Gets the boundary IDs with their names.
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
MeshGenerator for breaking all boundaries based on which block they are attached to.
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)
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:32
void set_union(T &data, const unsigned int root_id) const