www.mooseframework.org
AllSideSetsByNormalsGenerator.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 "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 
28 template <>
31 {
33 
34  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
35 
36  return params;
37 }
38 
40  : SideSetsGeneratorBase(parameters), _input(getMesh("input"))
41 {
42 }
43 
44 std::unique_ptr<MeshBase>
46 {
47  _mesh->errorIfDistributedMesh("AddAllSideSetsByNormals");
48 
49  std::unique_ptr<MeshBase> mesh = std::move(_input);
50  setup(*mesh);
51 
52  // Get the current list of boundaries so we can generate new ones that won't conflict
53  _mesh_boundary_ids = mesh->get_boundary_info().get_boundary_ids();
54 
55  // Create the map object that will be owned by MooseMesh
56  using map_type = std::map<boundary_id_type, RealVectorValue>;
57  std::unique_ptr<map_type> boundary_map = libmesh_make_unique<map_type>();
58 
59  _visited.clear();
60 
61  // We'll need to loop over all of the elements to find ones that match this normal.
62  // We can't rely on flood catching them all here...
63  for (const auto & elem : mesh->element_ptr_range())
64  for (unsigned int side = 0; side < elem->n_sides(); ++side)
65  {
66  if (elem->neighbor_ptr(side))
67  continue;
68 
69  _fe_face->reinit(elem, side);
70  const std::vector<Point> & normals = _fe_face->get_normals();
71 
72  {
73  // See if we've seen this normal before (linear search)
74  const map_type::value_type * item = nullptr;
75  for (const auto & id_pair : *boundary_map)
76  if (std::abs(1.0 - id_pair.second * normals[0]) < 1e-5)
77  {
78  item = &id_pair;
79  break;
80  }
81 
82  if (item)
83  flood(elem, normals[0], item->first, *mesh);
84  else
85  {
86  boundary_id_type id = getNextBoundaryID();
87  (*boundary_map)[id] = normals[0];
88  flood(elem, normals[0], id, *mesh);
89  }
90  }
91  }
92 
93  finalize();
94 
95  return dynamic_pointer_cast<MeshBase>(mesh);
96 }
97 
98 boundary_id_type
100 {
101  std::set<boundary_id_type>::iterator it;
102  boundary_id_type next_id = 1;
103 
104  while ((it = _mesh_boundary_ids.find(next_id)) != _mesh_boundary_ids.end())
105  ++next_id;
106 
107  _mesh_boundary_ids.insert(next_id);
108 
109  return next_id;
110 }
registerMooseObject("MooseApp", AllSideSetsByNormalsGenerator)
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
InputParameters validParams< AllSideSetsByNormalsGenerator >()
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...
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...
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
std::unique_ptr< MeshBase > & _input
std::unique_ptr< FEBase > _fe_face
void flood(const Elem *elem, Point normal, 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...
InputParameters validParams< SideSetsGeneratorBase >()
std::shared_ptr< MooseMesh > & _mesh
References to the mesh and displaced mesh (currently in the ActionWarehouse)
Definition: MeshGenerator.h:72
std::map< boundary_id_type, std::set< const Elem * > > _visited
void setup(MeshBase &mesh)
This method is used to construct the FE object so we can compute normals of faces.