https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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 "MeshTraversingUtils.h"
14#include "MooseMeshUtils.h"
15#include "CastUniquePointer.h"
16#include "MooseApp.h"
17#include "MeshGeneratorSystem.h"
18
19#include "libmesh/mesh_generation.h"
20#include "libmesh/mesh.h"
21#include "libmesh/string_to_enum.h"
22#include "libmesh/quadrature_gauss.h"
23#include "libmesh/point_locator_base.h"
24#include "libmesh/distributed_mesh.h"
25#include "libmesh/elem.h"
26#include "libmesh/fe_base.h"
27
28#include <typeinfo>
29
31
34{
36
38 "Adds a new named sideset to the mesh for all faces matching the specified normal.");
39 params.addRequiredParam<std::vector<Point>>(
40 "normals", "A list of normals for which to start painting sidesets");
41
42 // We want to use a different normal_tol for this generator than from the base class to preserve
43 // old behavior.
44 params.setParameters("normal_tol", 1e-5);
45
46 // We are using 'normals' instead
47 params.suppressParameter<Point>("normal");
48
49 // It doesn't make sense to allow internal sides for this side set generator.
50 params.setParameters("include_only_external_sides", true);
51 params.suppressParameter<bool>("include_only_external_sides");
52
53 return params;
54}
55
57 : SideSetsGeneratorBase(parameters),
58 _normals(getParam<std::vector<Point>>("normals")),
59 _boundary_to_normal_map(
60 declareMeshProperty<std::map<BoundaryID, RealVectorValue>>("boundary_normals"))
61{
62 // Get the BoundaryIDs from the mesh
63 if (_normals.size() != _boundary_names.size())
64 mooseError("normal list and boundary list are not the same length");
65
66 // Make sure that the normals are normalized
67 for (auto & normal : _normals)
68 {
69 if (normal.norm() < 1e-5)
70 mooseError("Normal is zero");
71 normal /= normal.norm();
72 }
73
74 _using_normal = true;
75}
76
77std::unique_ptr<MeshBase>
79{
80 std::unique_ptr<MeshBase> mesh = std::move(_input);
81 if (!_fixed_normal && !mesh->is_replicated())
82 mooseError("SideSetsFromNormalsGenerator is not implemented for distributed meshes when "
83 "fixed_normal = false");
84
85 std::vector<BoundaryID> boundary_ids =
87
88 setup(*mesh);
89
90 _visited.clear();
91
92 // Request to compute normal vectors
93 const std::vector<Point> & face_normals = _fe_face->get_normals();
94
95 // We'll need to loop over all of the elements to find ones that match this normal.
96 // We can't rely on flood catching them all here...
97 for (const auto & elem : mesh->element_ptr_range())
98 for (const auto side : make_range(elem->n_sides()))
99 {
100 if (elem->neighbor_ptr(side))
101 continue;
102
103 _fe_face->reinit(elem, side);
104
105 // We'll just use the normal of the first qp
106 const Point & face_normal = face_normals[0];
107
108 for (const auto i : make_range(boundary_ids.size()))
109 {
111 flood(elem, _normals[i], boundary_ids[i], *mesh);
112 }
113 }
114
115 finalize();
116
117 BoundaryInfo & boundary_info = mesh->get_boundary_info();
118 for (const auto i : make_range(boundary_ids.size()))
119 {
120 boundary_info.sideset_name(boundary_ids[i]) = _boundary_names[i];
121 _boundary_to_normal_map[boundary_ids[i]] = _normals[i];
122 }
123
124 mesh->unset_is_prepared();
125 return dynamic_pointer_cast<MeshBase>(mesh);
126}
boundary_id_type BoundaryID
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
registerMooseObject("MooseApp", SideSetsFromNormalsGenerator)
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system.
void suppressParameter(const std::string &name)
This method suppresses an inherited parameter so that it isn't required or valid in the derived class...
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 addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump.
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.
A mesh generator to generate new sidesets from all faces matching the normal.
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
std::vector< Point > _normals
holds the normals used to generate sidesets
std::map< BoundaryID, RealVectorValue > & _boundary_to_normal_map
a map from the boundaries to the normals
SideSetsFromNormalsGenerator(const InputParameters &parameters)
void setup(MeshBase &mesh)
This method is used to construct the FE object so we can compute normals of faces.
const Real _normal_tol
if normal is specified, then faces are only added if face_normal.normal_hat <= 1 - normal_tol where n...
std::unique_ptr< libMesh::FEBase > _fe_face
std::vector< BoundaryName > _boundary_names
The list of new boundary names.
static InputParameters validParams()
std::unique_ptr< MeshBase > & _input
the mesh to add the sidesets to
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...
bool _using_normal
true if only faces close to "normal" will be added
void finalize()
This method finalizes the object, setting names back in the boundary_info object and releasing memory...
const bool _fixed_normal
Whether to fix the normal or allow it to vary to "paint" around curves.
std::map< boundary_id_type, std::set< const Elem * > > _visited
MeshBase & mesh
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.
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.