www.mooseframework.org
SideSetsFromBoundingBoxGenerator.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 "Conversion.h"
12 #include "MooseTypes.h"
13 #include "MooseMeshUtils.h"
14 #include "CastUniquePointer.h"
15 
16 #include "libmesh/distributed_mesh.h"
17 #include "libmesh/elem.h"
18 
19 #include <typeinfo>
20 
22 
23 template <>
26 {
28 
29  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
30  params.addClassDescription("Find sidesets with given boundary ids in bounding box and add new "
31  "boundary id. This can be done by finding all required boundary "
32  "and adding the new boundary id to those sidesets. Alternatively, "
33  "a number of boundary ids can be provided and all nodes within the "
34  "bounding box that have all the required boundary ids will have a new"
35  "boundary id added.");
36 
37  MooseEnum location("INSIDE OUTSIDE", "INSIDE");
38 
40  "bottom_left", "The bottom left point (in x,y,z with spaces in-between).");
42  "top_right", "The bottom left point (in x,y,z with spaces in-between).");
43  params.addRequiredParam<subdomain_id_type>(
44  "block_id", "Subdomain id to set for inside/outside the bounding box");
45  params.addRequiredParam<std::vector<BoundaryName>>(
46  "boundary_id_old", "Boundary id on specified block within the bounding box to select");
47  params.addRequiredParam<boundary_id_type>(
48  "boundary_id_new", "Boundary id on specified block within the bounding box to assign");
49  params.addParam<bool>("boundary_id_overlap",
50  false,
51  "Set to true if boundaries need to overlap on sideset to be detected.");
52  params.addParam<MooseEnum>(
53  "location", location, "Control of where the subdomain id is to be set");
54 
55  return params;
56 }
57 
59  const InputParameters & parameters)
60  : MeshGenerator(parameters),
61  _input(getMesh("input")),
62  _location(parameters.get<MooseEnum>("location")),
63  _block_id(parameters.get<SubdomainID>("block_id")),
64  _boundary_id_old(parameters.get<std::vector<BoundaryName>>("boundary_id_old")),
65  _boundary_id_new(parameters.get<boundary_id_type>("boundary_id_new")),
66  _bounding_box(parameters.get<RealVectorValue>("bottom_left"),
67  parameters.get<RealVectorValue>("top_right")),
68  _boundary_id_overlap(parameters.get<bool>("boundary_id_overlap"))
69 {
70  if (dynamic_pointer_cast<DistributedMesh>(_input) != nullptr)
71  mooseError("SideSetsFromBoundingBox only works with ReplicatedMesh.");
72 }
73 
74 std::unique_ptr<MeshBase>
76 {
77  std::unique_ptr<MeshBase> mesh = std::move(_input);
78 
79  // Get a reference to our BoundaryInfo object for later use
80  BoundaryInfo & boundary_info = mesh->get_boundary_info();
81  boundary_info.build_node_list_from_side_list();
82 
83  bool found_element = false;
84  bool found_side_sets = false;
85 
87  {
88  // Loop over the elements
89  for (const auto & elem : mesh->active_element_ptr_range())
90  {
91  // boolean if element centroid is in bounding box
92  bool contains = _bounding_box.contains_point(elem->centroid());
93 
94  // check if active elements are found in the bounding box
95  if (contains)
96  {
97  found_element = true;
98  // loop over sides of elements within bounding box
99  for (unsigned int side = 0; side < elem->n_sides(); side++)
100  // loop over provided boundary vector to check all side sets for all boundary ids
101  for (unsigned int boundary_id_number = 0; boundary_id_number < _boundary_id_old.size();
102  boundary_id_number++)
103  // check if side has same boundary id that you are looking for
104  if (boundary_info.has_boundary_id(
105  elem, side, boundary_info.get_id_by_name(_boundary_id_old[boundary_id_number])))
106  {
107  // assign new boundary value to boundary which meets meshmodifier criteria
108  boundary_info.add_side(elem, side, _boundary_id_new);
109  found_side_sets = true;
110  }
111  }
112  }
113  if (!found_element)
114  mooseError("No elements found within the bounding box");
115 
116  if (!found_side_sets)
117  mooseError("No side sets found on active elements within the bounding box");
118  }
119 
120  else if (_boundary_id_overlap)
121  {
122  if (_boundary_id_old.size() < 2)
123  mooseError("boundary_id_old out of bounds: ",
124  _boundary_id_old.size(),
125  " Must be 2 boundary inputs or more.");
126 
127  bool found_node = false;
128  const bool inside = (_location == "INSIDE");
129 
130  // Loop over the elements and assign node set id to nodes within the bounding box
131  for (auto node = mesh->active_nodes_begin(); node != mesh->active_nodes_end(); ++node)
132  {
133  // check if nodes are inside of bounding box
134  if (_bounding_box.contains_point(**node) == inside)
135  {
136  // read out boundary ids for nodes
137  std::vector<boundary_id_type> boundary_id_list;
138  boundary_info.boundary_ids(*node, boundary_id_list);
139  std::vector<boundary_id_type> boundary_id_old_list =
141 
142  // sort boundary ids on node and sort boundary ids provided in input file
143  std::sort(boundary_id_list.begin(), boundary_id_list.end());
144  std::sort(boundary_id_old_list.begin(), boundary_id_old_list.end());
145 
146  // check if input boundary ids are all contained in the node
147  // if true, write new boundary id on respective node
148  if (std::includes(boundary_id_list.begin(),
149  boundary_id_list.end(),
150  boundary_id_old_list.begin(),
151  boundary_id_old_list.end()))
152  {
153  boundary_info.add_node(*node, _boundary_id_new);
154  found_node = true;
155  }
156  }
157  }
158 
159  if (!found_node)
160  mooseError("No nodes found within the bounding box");
161  }
162 
163  return dynamic_pointer_cast<MeshBase>(mesh);
164 }
boundary_id_type _boundary_id_new
boundary ID to assign
SideSetsFromBoundingBoxGenerator(const InputParameters &parameters)
VectorValue< Real > RealVectorValue
Definition: Assembly.h:31
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.
void mooseError(Args &&... args) const
Definition: MooseObject.h:147
MeshGenerator for defining a Subdomain inside or outside of a bounding box.
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...
BoundingBox _bounding_box
Bounding box for testing element centroids against.
registerMooseObject("MooseApp", SideSetsFromBoundingBoxGenerator)
InputParameters validParams< SideSetsFromBoundingBoxGenerator >()
This is a "smart" enum class intended to replace many of the shortcomings in the C++ enum type It sho...
Definition: MooseEnum.h:31
subdomain_id_type SubdomainID
MooseEnum _location
ID location (inside of outside of box)
std::vector< libMesh::boundary_id_type > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown)
const bool _boundary_id_overlap
Flag to determine if the provided boundaries need to overlap.
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...
std::vector< BoundaryName > _boundary_id_old
boundary ID to select
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
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:30