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/elem.h" 22 #include "libmesh/remote_elem.h" 28 params.
addRequiredParam<MeshGeneratorName>(
"input",
"The mesh we want to modify");
30 "new_boundary",
"The list of boundary names to create on the supplied subdomain");
31 params.
addParam<
bool>(
"fixed_normal",
33 "This Boolean determines whether we fix our normal " 34 "or allow it to vary to \"paint\" around curves");
38 "If true, replace the old sidesets. If false, the current sidesets (if " 39 "any) will be preserved.");
41 params.
addParam<std::vector<BoundaryName>>(
42 "included_boundaries",
43 "A set of boundary names or ids whose sides will be included in the new sidesets. A side " 44 "is only added if it also belongs to one of these boundaries.");
45 params.
addParam<std::vector<BoundaryName>>(
46 "excluded_boundaries",
47 "A set of boundary names or ids whose sides will be excluded from the new sidesets. A side " 48 "is only added if does not belong to any of these boundaries.");
49 params.
addParam<std::vector<SubdomainName>>(
50 "included_subdomains",
51 "A set of subdomain names or ids whose sides will be included in the new sidesets. A side " 52 "is only added if the subdomain id of the corresponding element is in this set.");
53 params.
addParam<std::vector<SubdomainName>>(
"included_neighbors",
54 "A set of neighboring subdomain names or ids. A face " 55 "is only added if the subdomain id of the " 56 "neighbor is in this set");
58 "include_only_external_sides",
60 "Whether to only include external sides when considering sides to add to the sideset");
64 "If supplied, only faces with normal equal to this, up to " 65 "normal_tol, will be added to the sidesets specified");
68 "normal_tol>=0 & normal_tol<=2",
69 "If normal is supplied then faces are " 70 "only added if face_normal.normal_hat >= " 71 "1 - normal_tol, where normal_hat = " 73 params.
addParam<
Real>(
"variance",
"The variance allowed when comparing normals");
78 "included_boundaries excluded_boundaries included_subdomains included_neighbors " 79 "include_only_external_sides normal normal_tol",
80 "Sideset restrictions");
87 _input(getMesh(
"input")),
88 _boundary_names(
std::vector<BoundaryName>()),
89 _fixed_normal(getParam<bool>(
"fixed_normal")),
90 _replace(getParam<bool>(
"replace")),
91 _check_included_boundaries(isParamValid(
"included_boundaries")),
92 _check_excluded_boundaries(isParamValid(
"excluded_boundaries")),
93 _check_subdomains(isParamValid(
"included_subdomains")),
94 _check_neighbor_subdomains(isParamValid(
"included_neighbors")),
99 _include_only_external_sides(getParam<bool>(
"include_only_external_sides")),
100 _using_normal(isParamSetByUser(
"normal")),
101 _normal(_using_normal ? Point(getParam<Point>(
"normal") / getParam<Point>(
"normal").
norm())
102 : getParam<Point>(
"normal")),
103 _normal_tol(getParam<
Real>(
"normal_tol"))
114 mooseAssert(
_fe_face ==
nullptr,
"FE Face has already been initialized");
117 if (!
mesh.is_prepared())
118 mesh.prepare_for_use();
119 const auto dim =
mesh.mesh_dimension();
123 Utility::string_to_enum<libMesh::FEFamily>(
"MONOMIAL"));
132 paramError(
"include_only_external_sides",
"External sides dont have neighbors");
136 const auto & included_boundaries = getParam<std::vector<BoundaryName>>(
"included_boundaries");
138 if (std::find(included_boundaries.begin(), included_boundaries.end(), boundary_name) !=
139 included_boundaries.end())
142 "A boundary cannot be both the new boundary and be included in the list of included " 143 "boundaries. If you are trying to restrict an existing boundary, you must use a " 144 "different name for 'new_boundary', delete the old boundary, and then rename the " 145 "new boundary to the old boundary.");
154 included_boundaries[i],
155 "' was not found within the mesh");
160 const auto & excluded_boundaries = getParam<std::vector<BoundaryName>>(
"excluded_boundaries");
162 if (std::find(excluded_boundaries.begin(), excluded_boundaries.end(), boundary_name) !=
163 excluded_boundaries.end())
166 "A boundary cannot be both the new boundary and be excluded in the list of excluded " 175 excluded_boundaries[i],
176 "' was not found within the mesh");
185 "'included_boundaries' and 'excluded_boundaries' lists should not overlap");
193 const auto subdomains = getParam<std::vector<SubdomainName>>(
"included_subdomains");
194 for (
const auto &
name : subdomains)
196 paramError(
"included_subdomains",
"The block '",
name,
"' was not found in the mesh");
204 const auto subdomains = getParam<std::vector<SubdomainName>>(
"included_neighbors");
205 for (
const auto &
name : subdomains)
207 paramError(
"included_neighbors",
"The block '",
name,
"' was not found in the mesh");
230 const Point & normal,
245 const std::vector<Point> & face_normals =
_fe_face->get_normals();
247 for (
const auto side :
make_range(elem->n_sides()))
252 const Point face_normal = face_normals[0];
258 mesh.get_boundary_info().remove_side(elem, side);
260 mesh.get_boundary_info().add_side(elem, side,
side_id);
261 for (
const auto neighbor :
make_range(elem->n_sides()))
274 const Point & normal_2,
275 const Real & tol)
const 277 return (1.0 - normal_1 * normal_2) <= tol;
282 const Elem *
const elem,
const std::vector<subdomain_id_type> & subdomain_id_list)
const 285 return std::find(subdomain_id_list.begin(), subdomain_id_list.end(), curr_subdomain) !=
286 subdomain_id_list.end();
291 const unsigned int side,
292 const MeshBase & mesh)
const 295 if (
mesh.get_boundary_info().has_boundary_id(elem, side, bid))
302 const unsigned int side,
303 const MeshBase & mesh)
const 306 if (
mesh.get_boundary_info().has_boundary_id(elem, side, bid))
313 const unsigned int side,
314 const MeshBase & mesh,
315 const Point & desired_normal,
316 const Point & face_normal)
332 const Elem *
const neighbor = elem->neighbor_ptr(side);
bool elementSubdomainIdInList(const Elem *const elem, const std::vector< subdomain_id_type > &subdomain_id_list) const
Determines whether the given element's subdomain id is in the given subdomain_id_list.
std::unique_ptr< FEGenericBase< Real > > build(const unsigned int dim, const FEType &fet)
const bool _fixed_normal
Whether to fix the normal or allow it to vary to "paint" around curves.
bool elemSideSatisfiesRequirements(const Elem *const elem, const unsigned int side, const MeshBase &mesh, const Point &normal, const Point &face_normal)
Determines whether the given element's side satisfies the following parameters: include_only_external...
const Real _normal_tol
if normal is specified, then faces are only added if face_normal.normal_hat <= 1 - normal_tol where n...
const BoundaryID INVALID_BOUNDARY_ID
std::vector< subdomain_id_type > _included_neighbor_subdomain_ids
A list of included neighbor subdomain ids that the sides' neighbor element must be a part of...
const boundary_id_type side_id
SideSetsGeneratorBase(const InputParameters ¶meters)
const bool _check_included_boundaries
whether to check boundary ids against the included boundary list when adding sides or not ...
const bool _replace
Whether or not to remove the old sidesets (all of them, if any) when adding sidesets.
static constexpr std::size_t dim
This is the dimension of all vector and tensor datastructures used in MOOSE.
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::vector< subdomain_id_type > getSubdomainIDs(const libMesh::MeshBase &mesh, const std::vector< SubdomainName > &subdomain_name)
Get the associated subdomainIDs for the subdomain names that are passed in.
virtual const std::string & name() const
Get the name of the class.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
std::vector< subdomain_id_type > _included_subdomain_ids
A list of included subdomain ids that the side has to be part of, extracted from the included_subdoma...
const bool _include_only_external_sides
Whether to only include external side when considering sides to add to the sideset.
const bool _check_excluded_boundaries
whether to check boundary ids against the excluded boundary list when adding sides or not ...
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 elementSideInIncludedBoundaries(const Elem *const elem, const unsigned int side, const MeshBase &mesh) const
Determines whether the given side of an element belongs to any boundaries in the included_boundaries ...
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.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
static InputParameters validParams()
void finalize()
This method finalizes the object, setting names back in the boundary_info object and releasing memory...
virtual ~SideSetsGeneratorBase()
static InputParameters validParams()
bool _using_normal
true if only faces close to "normal" will be added
std::vector< boundary_id_type > _included_boundary_ids
A list of boundary ids that the side has to be part of, extracted from the included_boundaries parame...
bool hasSubdomainName(const MeshBase &input_mesh, const SubdomainName &name)
Whether a particular subdomain name exists in the mesh.
const bool _check_subdomains
whether to check subdomain ids of the element in the (element, side, boundary id) tuple when adding s...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
IntRange< T > make_range(T beg, T end)
const InputParameters & parameters() const
Get the parameters of the object.
std::vector< boundary_id_type > _excluded_boundary_ids
A list of boundary ids that the side must not be a part of, extracted from the excluded_boundaries pa...
std::unique_ptr< libMesh::QGauss > _qface
bool elementSideInExcludedBoundaries(const Elem *const elem, const unsigned int side, const MeshBase &mesh) const
Determines whether the given side of an element belongs to any boundaries in the excluded_boundaries ...
const bool _check_neighbor_subdomains
whether to check the subdomain ids of the neighbor element (on the other 'side' of the side) when add...
std::map< boundary_id_type, std::set< const Elem * > > _visited
std::unique_ptr< libMesh::FEBase > _fe_face
MeshGenerators are objects that can modify or add to an existing mesh.
void setup(MeshBase &mesh)
This method is used to construct the FE object so we can compute normals of faces.
auto index_range(const T &sizable)
const RemoteElem * remote_elem