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 = " 76 "included_boundaries excluded_boundaries included_subdomains included_neighbors " 77 "include_only_external_sides normal normal_tol",
78 "Sideset restrictions");
85 _input(getMesh(
"input")),
86 _boundary_names(
std::vector<BoundaryName>()),
87 _fixed_normal(getParam<bool>(
"fixed_normal")),
88 _replace(getParam<bool>(
"replace")),
89 _check_included_boundaries(isParamValid(
"included_boundaries")),
90 _check_excluded_boundaries(isParamValid(
"excluded_boundaries")),
91 _check_subdomains(isParamValid(
"included_subdomains")),
92 _check_neighbor_subdomains(isParamValid(
"included_neighbors")),
97 _include_only_external_sides(getParam<bool>(
"include_only_external_sides")),
98 _using_normal(isParamSetByUser(
"normal")),
99 _normal(_using_normal ? Point(getParam<Point>(
"normal") / getParam<Point>(
"normal").
norm())
100 : getParam<Point>(
"normal")),
101 _normal_tol(getParam<
Real>(
"normal_tol"))
112 mooseAssert(
_fe_face ==
nullptr,
"FE Face has already been initialized");
115 if (!
mesh.is_prepared())
116 mesh.prepare_for_use();
117 const auto dim =
mesh.mesh_dimension();
121 Utility::string_to_enum<libMesh::FEFamily>(
"MONOMIAL"));
130 paramError(
"include_only_external_sides",
"External sides dont have neighbors");
134 const auto & included_boundaries = getParam<std::vector<BoundaryName>>(
"included_boundaries");
136 if (
std::find(included_boundaries.begin(), included_boundaries.end(), boundary_name) !=
137 included_boundaries.end())
140 "A boundary cannot be both the new boundary and be included in the list of included " 141 "boundaries. If you are trying to restrict an existing boundary, you must use a " 142 "different name for 'new_boundary', delete the old boundary, and then rename the " 143 "new boundary to the old boundary.");
152 included_boundaries[i],
153 "' was not found within the mesh");
158 const auto & excluded_boundaries = getParam<std::vector<BoundaryName>>(
"excluded_boundaries");
160 if (
std::find(excluded_boundaries.begin(), excluded_boundaries.end(), boundary_name) !=
161 excluded_boundaries.end())
164 "A boundary cannot be both the new boundary and be excluded in the list of excluded " 173 excluded_boundaries[i],
174 "' was not found within the mesh");
183 "'included_boundaries' and 'excluded_boundaries' lists should not overlap");
191 const auto subdomains = getParam<std::vector<SubdomainName>>(
"included_subdomains");
192 for (
const auto &
name : subdomains)
194 paramError(
"included_subdomains",
"The block '",
name,
"' was not found in the mesh");
202 const auto subdomains = getParam<std::vector<SubdomainName>>(
"included_neighbors");
203 for (
const auto &
name : subdomains)
205 paramError(
"included_neighbors",
"The block '",
name,
"' was not found in the mesh");
228 const Point & normal,
243 const std::vector<Point> & face_normals =
_fe_face->get_normals();
245 for (
const auto side :
make_range(elem->n_sides()))
250 const Point face_normal = face_normals[0];
256 mesh.get_boundary_info().remove_side(elem, side);
258 mesh.get_boundary_info().add_side(elem, side,
side_id);
259 for (
const auto neighbor :
make_range(elem->n_sides()))
272 const Point & normal_2,
273 const Real & tol)
const 275 return (1.0 - normal_1 * normal_2) <= tol;
280 const Elem *
const elem,
const std::vector<subdomain_id_type> & subdomain_id_list)
const 283 return std::find(subdomain_id_list.begin(), subdomain_id_list.end(), curr_subdomain) !=
284 subdomain_id_list.end();
289 const unsigned int side,
290 const MeshBase & mesh)
const 293 if (
mesh.get_boundary_info().has_boundary_id(elem, side, bid))
300 const unsigned int side,
301 const MeshBase & mesh)
const 304 if (
mesh.get_boundary_info().has_boundary_id(elem, side, bid))
311 const unsigned int side,
312 const MeshBase & mesh,
313 const Point & desired_normal,
314 const Point & face_normal)
330 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.
KOKKOS_INLINE_FUNCTION const T * find(const T &target, const T *const begin, const T *const end)
Find a value in an array.
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...
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 ...
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 InputParameters & parameters() const
Get the parameters of the object.
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.
const std::string & name() const
Get the name of the class.
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.
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)
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 ...
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
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