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 #include "MooseUtils.h"
16 
17 #include "libmesh/distributed_mesh.h"
18 #include "libmesh/elem.h"
19 
20 #include <typeinfo>
21 
23 
26 {
28 
29  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
30  params.addClassDescription("Defines new sidesets using currently-defined sideset IDs inside or "
31  "outside of a bounding box.");
32 
33  MooseEnum location("INSIDE OUTSIDE", "INSIDE");
34 
36  "bottom_left", "The bottom left point (in x,y,z with spaces in-between).");
38  "top_right", "The bottom left point (in x,y,z with spaces in-between).");
40  "block_id",
41  "Subdomain id to set for inside/outside the bounding box",
42  "The parameter 'block_id' is not used.");
43  params.addDeprecatedParam<std::vector<BoundaryName>>(
44  "boundary_id_old",
45  "Boundary id on specified block within the bounding box to select",
46  "boundary_id_old is deprecated, use boundaries_old with names or ids");
47  params.addDeprecatedParam<BoundaryName>(
48  "boundary_id_new",
49  "Boundary id on specified block within the bounding box to assign",
50  "boundary_id_new is deprecated, use boundary_new with a name or id");
51  params.addParam<std::vector<BoundaryName>>(
52  "boundaries_old",
53  "The list of boundaries on the specified block within the bounding box to be modified");
54  params.addParam<BoundaryName>("boundary_new",
55  "Boundary on specified block within the bounding box to assign");
56  params.addParam<bool>("boundary_id_overlap",
57  false,
58  "Set to true if boundaries need to overlap on sideset to be detected.");
59  params.addParam<MooseEnum>(
60  "location", location, "Control of where the subdomain id is to be set");
61 
62  return params;
63 }
64 
66  const InputParameters & parameters)
67  : MeshGenerator(parameters),
68  _input(getMesh("input")),
69  _location(parameters.get<MooseEnum>("location")),
70  _bounding_box(MooseUtils::buildBoundingBox(parameters.get<RealVectorValue>("bottom_left"),
71  parameters.get<RealVectorValue>("top_right"))),
72  _boundary_id_overlap(parameters.get<bool>("boundary_id_overlap"))
73 {
74  if (parameters.isParamSetByUser("boundaries_old"))
75  _boundaries_old = parameters.get<std::vector<BoundaryName>>("boundaries_old");
76  else if (parameters.isParamSetByUser("boundary_id_old"))
77  _boundaries_old = parameters.get<std::vector<BoundaryName>>("boundary_id_old");
78  else
79  mooseError("Either boundaries_old or boundary_id_old (deprecated) must be specified.");
80 
81  if (parameters.isParamSetByUser("boundary_new"))
82  _boundary_new = parameters.get<BoundaryName>("boundary_new");
83  else if (parameters.isParamSetByUser("boundary_id_new"))
84  _boundary_new = parameters.get<BoundaryName>("boundary_id_new");
85  else
86  mooseError("Either boundary_new or boundary_id_new (deprecated) must be specified.");
87 }
88 
89 std::unique_ptr<MeshBase>
91 {
92  std::unique_ptr<MeshBase> mesh = std::move(_input);
93  if (!mesh->is_replicated())
94  mooseError("SideSetsFromBoundingBoxGenerator is not implemented for distributed meshes");
95 
96  // Get a reference to our BoundaryInfo object for later use
97  BoundaryInfo & boundary_info = mesh->get_boundary_info();
98  boundary_info.build_node_list_from_side_list();
99 
100  bool found_element = false;
101  bool found_side_sets = false;
102  const bool inside = (_location == "INSIDE");
103 
104  // Get the list of boundary ids from the boundary names
105  auto boundary_ids = MooseMeshUtils::getBoundaryIDs(*mesh, _boundaries_old, false);
106 
107  // Check that the old boundary ids/names exist in the mesh
108  for (std::size_t i = 0; i < boundary_ids.size(); ++i)
109  if (boundary_ids[i] == Moose::INVALID_BOUNDARY_ID)
110  paramError(
111  "boundaries", "The boundary '", _boundaries_old[i], "' was not found within the mesh");
112 
113  // Attempt to get the new boundary id from the name
114  auto boundary_id_new = MooseMeshUtils::getBoundaryID(_boundary_new, *mesh);
115 
116  // If the new boundary id is not valid, make it instead
117  if (boundary_id_new == Moose::INVALID_BOUNDARY_ID)
118  {
119  boundary_id_new = MooseMeshUtils::getNextFreeBoundaryID(*mesh);
120 
121  // Write the name alias of the boundary id to the mesh boundary info
122  boundary_info.sideset_name(boundary_id_new) = _boundary_new;
123  boundary_info.nodeset_name(boundary_id_new) = _boundary_new;
124  }
125 
127  {
128  // Loop over the elements
129  for (const auto & elem : mesh->active_element_ptr_range())
130  {
131  // boolean if element centroid is in bounding box
132  bool contains = _bounding_box.contains_point(elem->vertex_average());
133 
134  // check if active elements are found either in or out of the bounding box, apropos "inside"
135  if (contains == inside)
136  {
137  found_element = true;
138  // loop over sides of elements within bounding box
139  for (unsigned int side = 0; side < elem->n_sides(); side++)
140  // loop over provided boundary vector to check all side sets for all boundary ids
141  for (auto boundary_id : boundary_ids)
142  // check if side has same boundary id that you are looking for
143  if (boundary_info.has_boundary_id(elem, side, boundary_id))
144  {
145  // assign new boundary value to boundary which meets meshmodifier criteria
146  boundary_info.add_side(elem, side, boundary_id_new);
147  found_side_sets = true;
148  }
149  }
150  }
151  if (!found_element && inside)
152  mooseError("No elements found within the bounding box");
153 
154  if (!found_element && !inside)
155  mooseError("No elements found outside the bounding box");
156 
157  if (!found_side_sets)
158  mooseError("No side sets found on active elements within the bounding box");
159  }
160 
161  else if (_boundary_id_overlap)
162  {
163  if (boundary_ids.size() < 2)
164  mooseError("boundary_id_old out of bounds: ",
165  boundary_ids.size(),
166  " Must be 2 boundary inputs or more.");
167 
168  bool found_node = false;
169 
170  // Loop over the elements and assign node set id to nodes within the bounding box
171  for (auto node = mesh->active_nodes_begin(); node != mesh->active_nodes_end(); ++node)
172  {
173  // check if nodes are inside of bounding box
174  if (_bounding_box.contains_point(**node) == inside)
175  {
176  // read out boundary ids for nodes
177  std::vector<boundary_id_type> node_boundary_ids;
178  boundary_info.boundary_ids(*node, node_boundary_ids);
179 
180  // sort boundary ids on node and sort boundary ids provided in input file
181  std::sort(node_boundary_ids.begin(), node_boundary_ids.end());
182  std::sort(boundary_ids.begin(), boundary_ids.end());
183 
184  // check if input boundary ids are all contained in the node
185  // if true, write new boundary id on respective node
186  if (std::includes(node_boundary_ids.begin(),
187  node_boundary_ids.end(),
188  boundary_ids.begin(),
189  boundary_ids.end()))
190  {
191  boundary_info.add_node(*node, boundary_id_new);
192  found_node = true;
193  }
194  }
195  }
196 
197  if (!found_node)
198  mooseError("No nodes found within the bounding box");
199  }
200 
201  mesh->set_isnt_prepared();
202  return dynamic_pointer_cast<MeshBase>(mesh);
203 }
void addDeprecatedParam(const std::string &name, const T &value, const std::string &doc_string, const std::string &deprecation_message)
SideSetsFromBoundingBoxGenerator(const InputParameters &parameters)
const BoundaryID INVALID_BOUNDARY_ID
Definition: MooseTypes.C:24
std::vector< std::pair< R1, R2 > > get(const std::string &param1, const std::string &param2) const
Combine two vector parameters into a single vector of pairs.
T * get(const std::unique_ptr< T > &u)
The MooseUtils::get() specializations are used to support making forwards-compatible code changes fro...
Definition: MooseUtils.h:1147
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
BoundaryName _boundary_new
New boundary to assign.
MeshBase & 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.
MeshGenerator for defining sidesets 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...
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
Gets the boundary ID associated with the given BoundaryName.
std::vector< BoundaryName > _boundaries_old
List of boundary names to select.
BoundingBox _bounding_box
Bounding box for testing element centroids against.
registerMooseObject("MooseApp", 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
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
MooseEnum _location
ID location (inside of outside of box)
const bool _boundary_id_overlap
Flag to determine if the provided boundaries need to overlap.
bool isParamSetByUser(const std::string &name) const
Method returns true if the parameter was by the user.
BoundingBox buildBoundingBox(const Point &p1, const Point &p2)
Construct a valid bounding box from 2 arbitrary points.
Definition: MooseUtils.C:1223
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
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...
const InputParameters & parameters() const
Get the parameters of the object.
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...
BoundaryID getNextFreeBoundaryID(MeshBase &input_mesh)
Checks input mesh and returns the largest boundary ID in the mesh plus one, which is a boundary ID in...
MeshGenerators are objects that can modify or add to an existing mesh.
Definition: MeshGenerator.h:32