https://mooseframework.inl.gov
SideSetsFromAllNormalsGenerator.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 #include "MeshTraversingUtils.h"
15 
16 #include "libmesh/fe_base.h"
17 #include "libmesh/mesh_generation.h"
18 #include "libmesh/mesh.h"
19 #include "libmesh/string_to_enum.h"
20 #include "libmesh/quadrature_gauss.h"
21 #include "libmesh/point_locator_base.h"
22 #include "libmesh/distributed_mesh.h"
23 #include "libmesh/elem.h"
24 
25 #include <typeinfo>
26 
29  AllSideSetsByNormalsGenerator,
30  "06/30/2027 24:00",
32 
35 {
37 
38  // This is the expected behavior of this sideset generator
39  params.setParameters("include_only_external_sides", true);
40  params.suppressParameter<bool>("include_only_external_sides");
41 
42  // The normals are found from the actual orientation of sidesets, not user-specified
43  params.suppressParameter<bool>("fixed_normal");
44  params.suppressParameter<Point>("normal");
45  params.suppressParameter<Real>("normal_tol");
46  params.suppressParameter<std::vector<BoundaryName>>("new_boundary");
47 
48  params.addClassDescription("Adds sidesets to the entire mesh based on unique normals.");
49  return params;
50 }
51 
53  : SideSetsGeneratorBase(parameters),
54  _boundary_to_normal_map(
55  declareMeshProperty<std::map<BoundaryID, RealVectorValue>>("boundary_normals"))
56 {
57 }
58 
59 std::unique_ptr<MeshBase>
61 {
62  std::unique_ptr<MeshBase> mesh = std::move(_input);
63  if (!mesh->is_replicated())
64  mooseError("SideSetsFromAllNormalsGenerator is not implemented for distributed meshes");
65  setup(*mesh);
66 
67  // Get the current list of boundaries so we can generate new ones that won't conflict
68  _mesh_boundary_ids = mesh->get_boundary_info().get_boundary_ids();
69 
70  _visited.clear();
71 
72  // We'll need to loop over all of the elements to find ones that match this normal.
73  // We can't rely on flood catching them all here...
74  for (const auto & elem : mesh->element_ptr_range())
75  for (const auto side : make_range(elem->n_sides()))
76  {
77  const std::vector<Point> & normals = _fe_face->get_normals();
78  _fe_face->reinit(elem, side);
79 
80  {
81  // See if we've seen this normal before (linear search)
82  const std::map<BoundaryID, RealVectorValue>::value_type * item = nullptr;
83  for (const auto & id_pair : _boundary_to_normal_map)
84  if (MeshTraversingUtils::normalsWithinTol(id_pair.second, normals[0], 1e-5))
85  {
86  item = &id_pair;
87  break;
88  }
89 
90  if (item)
91  flood(elem, normals[0], item->first, *mesh);
92  else
93  {
95  _boundary_to_normal_map[id] = normals[0];
96  flood(elem, normals[0], id, *mesh);
97  }
98  }
99  }
100 
101  finalize();
102 
103  mesh->unset_is_prepared();
104  return dynamic_pointer_cast<MeshBase>(mesh);
105 }
106 
109 {
110  std::set<boundary_id_type>::iterator it;
111  boundary_id_type next_id = 1;
112 
113  while ((it = _mesh_boundary_ids.find(next_id)) != _mesh_boundary_ids.end())
114  ++next_id;
115 
116  _mesh_boundary_ids.insert(next_id);
117 
118  return next_id;
119 }
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...
SideSetsFromAllNormalsGenerator(const InputParameters &parameters)
std::unique_ptr< MeshBase > & _input
the mesh to add the sidesets to
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...
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.
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...
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
int8_t boundary_id_type
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...
void finalize()
This method finalizes the object, setting names back in the boundary_info object and releasing memory...
static InputParameters validParams()
registerMooseObjectRenamed("MooseApp", AllSideSetsByNormalsGenerator, "06/30/2027 24:00", SideSetsFromAllNormalsGenerator)
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:281
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...
registerMooseObject("MooseApp", SideSetsFromAllNormalsGenerator)
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...
bool normalsWithinTol(const Point &normal_1, const Point &normal_2, const Real tol)
Determines whether two normal vectors are within normal_tol of each other.
This class will add sidesets to the entire mesh based on unique normals.