17 #include "libmesh/mesh.h" 18 #include "libmesh/remote_elem.h" 19 #include "libmesh/point.h" 20 #include "libmesh/fe_base.h" 29 params.
renameParam(
"included_subdomains",
"block",
"The blocks around which to create sidesets");
38 "Adds element faces that are on the exterior of the given block to the sidesets specified");
49 std::unique_ptr<MeshBase>
52 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
59 std::vector<boundary_id_type> boundary_ids =
63 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
69 typedef std::vector<std::pair<dof_id_type, unsigned int>> vec_type;
70 std::vector<vec_type> queries(my_n_proc);
73 const std::vector<Point> & face_normals =
_fe_face->get_normals();
76 for (
const auto & elem :
mesh->active_element_ptr_range())
83 for (
const auto side :
make_range(elem->n_sides()))
85 const auto * neighbor = elem->neighbor_ptr(side);
92 queries[elem->processor_id()].push_back(std::make_pair(elem->id(), side));
98 const Point & face_normal = face_normals[0];
103 boundary_info.remove_side(elem, side);
104 for (
const auto & boundary_id : boundary_ids)
105 boundary_info.add_side(elem, side, boundary_id);
111 if (!
mesh->is_serial())
113 const auto queries_tag =
mesh->comm().get_unique_tag(),
114 replies_tag =
mesh->comm().get_unique_tag();
116 std::vector<Parallel::Request> side_requests(my_n_proc - 1), reply_requests(my_n_proc - 1);
124 Parallel::Request &
request = side_requests[p - (p > my_proc_id)];
126 mesh->comm().send(p, queries[p],
request, queries_tag);
130 std::vector<vec_type> responses(my_n_proc - 1);
136 Parallel::Status
status(
mesh->comm().probe(Parallel::any_source, queries_tag));
139 mesh->comm().receive(source_pid,
query, queries_tag);
141 Parallel::Request &
request = reply_requests[p - 1];
143 for (
const auto & q :
query)
145 const Elem * elem =
mesh->elem_ptr(q.first);
146 const unsigned int side = q.second;
150 const Point & face_normal =
_fe_face->get_normals()[0];
153 responses[p - 1].push_back(std::make_pair(elem->id(), side));
156 mesh->comm().send(source_pid, responses[p - 1],
request, replies_tag);
162 Parallel::Status
status(this->
comm().probe(Parallel::any_source, replies_tag));
167 this->
comm().
receive(source_pid, response, replies_tag);
169 for (
const auto & r : response)
171 const Elem * elem =
mesh->elem_ptr(r.first);
172 const unsigned int side = r.second;
175 boundary_info.remove_side(elem, side);
176 for (
const auto & boundary_id : boundary_ids)
177 boundary_info.add_side(elem, side, boundary_id);
181 Parallel::wait(side_requests);
182 Parallel::wait(reply_requests);
186 for (
unsigned int i = 0; i < boundary_ids.size(); ++i)
189 mesh->unset_is_prepared();
195 const unsigned int side)
const 197 const auto neighbor = elem->neighbor_ptr(side);
198 return (neighbor ==
nullptr) || (elem->subdomain_id() != neighbor->subdomain_id());
SideSetsAroundSubdomainGenerator(const InputParameters ¶meters)
bool elementSubdomainIdInList(const Elem *const elem, const std::vector< subdomain_id_type > &subdomain_id_list)
Determines whether the given element's subdomain id is in the given subdomain_id_list.
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...
std::unique_ptr< MeshBase > & _input
the mesh to add the sidesets to
Point _normal
if specified, then faces are only added if their normal is close to this
const bool _replace
Whether or not to remove the old sidesets (all of them, if any) when adding sidesets.
const Parallel::Communicator & comm() const
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.
uint8_t processor_id_type
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
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...
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()
static InputParameters validParams()
const bool _check_subdomains
whether to check subdomain ids of the element in the (element, side, boundary id) tuple when adding s...
IntRange< T > make_range(T beg, T end)
registerMooseObject("MooseApp", SideSetsAroundSubdomainGenerator)
bool elemSideOnBoundary(const Elem *const elem, const unsigned int side) const
Determine whether the given side of an element resides on an external or internal boundary...
Adds the faces on the boundary of given block to the sidesets specified by "boundary" Optionally...
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.
const RemoteElem * remote_elem