Loading [MathJax]/extensions/tex2jax.js
https://mooseframework.inl.gov
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends
SideSetsFromNormalsGenerator.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 "MooseMeshUtils.h"
14 #include "CastUniquePointer.h"
15 #include "MooseApp.h"
16 #include "MeshGeneratorSystem.h"
17 
18 #include "libmesh/mesh_generation.h"
19 #include "libmesh/mesh.h"
20 #include "libmesh/string_to_enum.h"
21 #include "libmesh/quadrature_gauss.h"
22 #include "libmesh/point_locator_base.h"
23 #include "libmesh/distributed_mesh.h"
24 #include "libmesh/elem.h"
25 #include "libmesh/fe_base.h"
26 
27 #include <typeinfo>
28 
30 
33 {
35 
36  params.addClassDescription(
37  "Adds a new named sideset to the mesh for all faces matching the specified normal.");
38  params.addRequiredParam<std::vector<Point>>(
39  "normals", "A list of normals for which to start painting sidesets");
40  params.addParam<Real>("tolerance", "Tolerance for comparing the face normal");
41  params.deprecateParam("tolerance", "normal_tol", "4/01/2025");
42 
43  // We want to use a different normal_tol for this generator than from the base class to preserve
44  // old behavior.
45  params.setParameters("normal_tol", 1e-5);
46 
47  // We are using 'normals' instead
48  params.suppressParameter<Point>("normal");
49 
50  // It doesn't make sense to allow internal sides for this side set generator.
51  params.setParameters("include_only_external_sides", true);
52  params.suppressParameter<bool>("include_only_external_sides");
53 
54  return params;
55 }
56 
58  : SideSetsGeneratorBase(parameters),
59  _normals(getParam<std::vector<Point>>("normals")),
60  _boundary_to_normal_map(
61  declareMeshProperty<std::map<BoundaryID, RealVectorValue>>("boundary_normals"))
62 {
63  // Get the BoundaryIDs from the mesh
64  if (_normals.size() != _boundary_names.size())
65  mooseError("normal list and boundary list are not the same length");
66 
67  // Make sure that the normals are normalized
68  for (auto & normal : _normals)
69  {
70  if (normal.norm() < 1e-5)
71  mooseError("Normal is zero");
72  normal /= normal.norm();
73  }
74 
75  _using_normal = true;
76 }
77 
78 std::unique_ptr<MeshBase>
80 {
81  std::unique_ptr<MeshBase> mesh = std::move(_input);
82  if (!_fixed_normal && !mesh->is_replicated())
83  mooseError("SideSetsFromNormalsGenerator is not implemented for distributed meshes when "
84  "fixed_normal = false");
85 
86  std::vector<BoundaryID> boundary_ids =
88 
89  setup(*mesh);
90 
91  _visited.clear();
92 
93  // Request to compute normal vectors
94  const std::vector<Point> & face_normals = _fe_face->get_normals();
95 
96  // We'll need to loop over all of the elements to find ones that match this normal.
97  // We can't rely on flood catching them all here...
98  for (const auto & elem : mesh->element_ptr_range())
99  for (const auto side : make_range(elem->n_sides()))
100  {
101  if (elem->neighbor_ptr(side))
102  continue;
103 
104  _fe_face->reinit(elem, side);
105 
106  // We'll just use the normal of the first qp
107  const Point & face_normal = face_normals[0];
108 
109  for (const auto i : make_range(boundary_ids.size()))
110  {
111  if (normalsWithinTol(_normals[i], face_normal, _normal_tol))
112  flood(elem, _normals[i], boundary_ids[i], *mesh);
113  }
114  }
115 
116  finalize();
117 
118  BoundaryInfo & boundary_info = mesh->get_boundary_info();
119  for (const auto i : make_range(boundary_ids.size()))
120  {
121  boundary_info.sideset_name(boundary_ids[i]) = _boundary_names[i];
122  _boundary_to_normal_map[boundary_ids[i]] = _normals[i];
123  }
124 
125  // This is a terrible hack that we'll want to remove once BMBBG isn't terrible
127  mesh->set_isnt_prepared();
128  return dynamic_pointer_cast<MeshBase>(mesh);
129 }
const bool _fixed_normal
Whether to fix the normal or allow it to vary to "paint" around curves.
std::unique_ptr< MeshBase > & _input
the mesh to add the sidesets to
const Real _normal_tol
if normal is specified, then faces are only added if face_normal.normal_hat <= 1 - normal_tol where n...
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::vector< BoundaryName > _boundary_names
The list of new boundary names.
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::vector< Point > _normals
holds the normals used to generate sidesets
bool hasBreakMeshByBlockGenerator() const
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...
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...
SideSetsFromNormalsGenerator(const InputParameters &parameters)
void deprecateParam(const std::string &old_name, const std::string &new_name, const std::string &removal_date)
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...
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.
MooseApp & _app
The MOOSE application this is associated with.
Definition: MooseBase.h:84
void finalize()
This method finalizes the object, setting names back in the boundary_info object and releasing memory...
registerMooseObject("MooseApp", SideSetsFromNormalsGenerator)
static InputParameters validParams()
bool _using_normal
true if only faces close to "normal" will be added
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
A mesh generator to generate new sidesets from all faces matching the normal.
IntRange< T > make_range(T beg, T end)
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...
std::map< BoundaryID, RealVectorValue > & _boundary_to_normal_map
a map from the boundaries to the normals
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
MeshGeneratorSystem & getMeshGeneratorSystem()
Gets the system that manages the MeshGenerators.
Definition: MooseApp.h:862
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...