www.mooseframework.org
SideSetsFromNormalsGenerator.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 "MooseMeshUtils.h"
14 #include "CastUniquePointer.h"
15 
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 #include "libmesh/fe_base.h"
24 
25 #include <typeinfo>
26 
28 
29 template <>
32 {
34 
35  params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to modify");
36  params.addClassDescription(
37  "Adds a new named sideset to the mesh for all faces matching the specified normal.");
38  params.addRequiredParam<std::vector<BoundaryName>>("new_boundary",
39  "The name of the boundary to create");
40  params.addRequiredParam<std::vector<Point>>(
41  "normals", "A list of normals for which to start painting sidesets");
42 
43  return params;
44 }
45 
47  : SideSetsGeneratorBase(parameters),
48  _input(getMesh("input")),
49  _normals(getParam<std::vector<Point>>("normals"))
50 {
51  if (typeid(_input).name() == typeid(std::unique_ptr<DistributedMesh>).name())
52  mooseError("GenerateAllSideSetsByNormals only works with ReplicatedMesh.");
53 
54  // Get the BoundaryIDs from the mesh
55  _boundary_names = getParam<std::vector<BoundaryName>>("new_boundary");
56 
57  if (_normals.size() != _boundary_names.size())
58  mooseError("normal list and boundary list are not the same length");
59 
60  // Make sure that the normals are normalized
61  for (auto & normal : _normals)
62  {
63  mooseAssert(normal.norm() >= 1e-5, "Normal is zero");
64  normal /= normal.norm();
65  }
66 }
67 
68 std::unique_ptr<MeshBase>
70 {
71  std::unique_ptr<MeshBase> mesh = std::move(_input);
72 
73  std::vector<BoundaryID> boundary_ids =
75 
76  setup(*mesh);
77 
78  _visited.clear();
79 
80  // We'll need to loop over all of the elements to find ones that match this normal.
81  // We can't rely on flood catching them all here...
82  for (const auto & elem : mesh->element_ptr_range())
83  for (unsigned int side = 0; side < elem->n_sides(); ++side)
84  {
85  if (elem->neighbor_ptr(side))
86  continue;
87 
88  _fe_face->reinit(elem, side);
89  const std::vector<Point> & normals = _fe_face->get_normals();
90 
91  for (unsigned int i = 0; i < boundary_ids.size(); ++i)
92  {
93  if (std::abs(1.0 - _normals[i] * normals[0]) < 1e-5)
94  flood(elem, _normals[i], boundary_ids[i], *mesh);
95  }
96  }
97 
98  finalize();
99 
100  BoundaryInfo & boundary_info = mesh->get_boundary_info();
101  for (unsigned int i = 0; i < boundary_ids.size(); ++i)
102  boundary_info.sideset_name(boundary_ids[i]) = _boundary_names[i];
103 
104  return dynamic_pointer_cast<MeshBase>(mesh);
105 }
MetaPhysicL::DualNumber< T, D > abs(const MetaPhysicL::DualNumber< T, D > &in)
std::unique_ptr< MeshBase > & _input
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
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...
SideSetsFromNormalsGenerator(const InputParameters &parameters)
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...
void finalize()
This method finalizes the object, setting names back in the boundary_info object and releasing memory...
InputParameters validParams< SideSetsGeneratorBase >()
registerMooseObject("MooseApp", SideSetsFromNormalsGenerator)
std::vector< libMesh::boundary_id_type > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown)
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
std::vector< BoundaryName > _boundary_names
const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:59
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
InputParameters validParams< SideSetsFromNormalsGenerator >()
void setup(MeshBase &mesh)
This method is used to construct the FE object so we can compute normals of faces.