https://mooseframework.inl.gov
AllSideSetsByNormalsGenerator.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
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 "Parser.h"
12 #include "InputParameters.h"
13 #include "CastUniquePointer.h"
14 
15 #include "libmesh/fe_base.h"
16 #include "libmesh/mesh_generation.h"
17 #include "libmesh/mesh.h"
18 #include "libmesh/string_to_enum.h"
19 #include "libmesh/quadrature_gauss.h"
20 #include "libmesh/point_locator_base.h"
21 #include "libmesh/distributed_mesh.h"
22 #include "libmesh/elem.h"
23 
24 #include <typeinfo>
25 
27 
30 {
32 
33  // This is the expected behavior of this sideset generator
34  // This is the expected behavior of this sideset generator
35  params.setParameters("include_only_external_sides", true);
36  params.suppressParameter<bool>("include_only_external_sides");
37 
38  // The normals are found from the actual orientation of sidesets, not user-specified
39  // The normals are found from the actual orientation of sidesets, not user-specified
40  params.suppressParameter<bool>("fixed_normal");
41  params.suppressParameter<Point>("normal");
42  params.suppressParameter<Real>("normal_tol");
43  params.suppressParameter<std::vector<BoundaryName>>("new_boundary");
44 
45  params.addClassDescription("Adds sidesets to the entire mesh based on unique normals.");
46  return params;
47 }
48 
50  : SideSetsGeneratorBase(parameters),
51  _boundary_to_normal_map(
52  declareMeshProperty<std::map<BoundaryID, RealVectorValue>>("boundary_normals"))
53 {
54 }
55 
56 std::unique_ptr<MeshBase>
58 {
59  std::unique_ptr<MeshBase> mesh = std::move(_input);
60  if (!mesh->is_replicated())
61  mooseError("AllSideSetsByNormalsGenerator is not implemented for distributed meshes");
62  setup(*mesh);
63 
64  // Get the current list of boundaries so we can generate new ones that won't conflict
65  _mesh_boundary_ids = mesh->get_boundary_info().get_boundary_ids();
66 
67  _visited.clear();
68 
69  // We'll need to loop over all of the elements to find ones that match this normal.
70  // We can't rely on flood catching them all here...
71  for (const auto & elem : mesh->element_ptr_range())
72  for (const auto side : make_range(elem->n_sides()))
73  {
74  const std::vector<Point> & normals = _fe_face->get_normals();
75  _fe_face->reinit(elem, side);
76 
77  {
78  // See if we've seen this normal before (linear search)
79  const std::map<BoundaryID, RealVectorValue>::value_type * item = nullptr;
80  for (const auto & id_pair : _boundary_to_normal_map)
81  if (normalsWithinTol(id_pair.second, normals[0], 1e-5))
82  {
83  item = &id_pair;
84  break;
85  }
86 
87  if (item)
88  flood(elem, normals[0], item->first, *mesh);
89  else
90  {
92  _boundary_to_normal_map[id] = normals[0];
93  flood(elem, normals[0], id, *mesh);
94  }
95  }
96  }
97 
98  finalize();
99 
100  mesh->set_isnt_prepared();
101  return dynamic_pointer_cast<MeshBase>(mesh);
102 }
103 
106 {
107  std::set<boundary_id_type>::iterator it;
108  boundary_id_type next_id = 1;
109 
110  while ((it = _mesh_boundary_ids.find(next_id)) != _mesh_boundary_ids.end())
111  ++next_id;
112 
113  _mesh_boundary_ids.insert(next_id);
114 
115  return next_id;
116 }
registerMooseObject("MooseApp", AllSideSetsByNormalsGenerator)
std::unique_ptr< MeshBase > & _input
the mesh to add the sidesets to
MeshBase & mesh
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
bool normalsWithinTol(const Point &normal_1, const Point &normal_2, const Real &tol) const
Determines whether two normal vectors are within normal_tol of each other.
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.
std::set< boundary_id_type > _mesh_boundary_ids
A pointer to the Mesh&#39;s boundary set, this datastructure will be modified through this modifier...
void suppressParameter(const std::string &name)
This method suppresses an inherited parameter so that it isn&#39;t required or valid in the derived class...
int8_t boundary_id_type
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
boundary_id_type BoundaryID
void flood(const Elem *elem, const Point &normal, const boundary_id_type &side_id, MeshBase &mesh)
This method implements a recursive flood routine to paint a sideset of mesh to neighboring faces give...
This class will add sidesets to the entire mesh based on unique normals.
AllSideSetsByNormalsGenerator(const InputParameters &parameters)
void finalize()
This method finalizes the object, setting names back in the boundary_info object and releasing memory...
static InputParameters validParams()
std::map< BoundaryID, RealVectorValue > & _boundary_to_normal_map
Mesh meta data for holding the map from boundary IDs to the normals of the corresponding boundaries...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:267
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::map< boundary_id_type, std::set< const Elem * > > _visited
std::unique_ptr< libMesh::FEBase > _fe_face
void setup(MeshBase &mesh)
This method is used to construct the FE object so we can compute normals of faces.
void setParameters(const std::string &name, const T &value, Ts... extra_input_parameters)
Given a series of parameters names and values, sets each name to the corresponding value...