16 #include "libmesh/mesh.h" 17 #include "libmesh/remote_elem.h" 18 #include "libmesh/point.h" 19 #include "libmesh/fe_base.h" 28 params.
renameParam(
"included_subdomains",
"block",
"The blocks around which to create sidesets");
37 "Adds element faces that are on the exterior of the given block to the sidesets specified");
48 std::unique_ptr<MeshBase>
51 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
58 std::vector<boundary_id_type> boundary_ids =
62 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
68 typedef std::vector<std::pair<dof_id_type, unsigned int>> vec_type;
69 std::vector<vec_type> queries(my_n_proc);
72 const std::vector<Point> & face_normals =
_fe_face->get_normals();
75 for (
const auto & elem :
mesh->active_element_ptr_range())
81 for (
const auto side :
make_range(elem->n_sides()))
83 const Elem * neighbor = elem->neighbor_ptr(side);
90 queries[elem->processor_id()].push_back(std::make_pair(elem->id(), side));
96 const Point & face_normal = face_normals[0];
101 boundary_info.remove_side(elem, side);
102 for (
const auto & boundary_id : boundary_ids)
103 boundary_info.add_side(elem, side, boundary_id);
109 if (!
mesh->is_serial())
111 const auto queries_tag =
mesh->comm().get_unique_tag(),
112 replies_tag =
mesh->comm().get_unique_tag();
114 std::vector<Parallel::Request> side_requests(my_n_proc - 1), reply_requests(my_n_proc - 1);
122 Parallel::Request &
request = side_requests[p - (p > my_proc_id)];
124 mesh->comm().send(p, queries[p],
request, queries_tag);
128 std::vector<vec_type> responses(my_n_proc - 1);
134 Parallel::Status
status(
mesh->comm().probe(Parallel::any_source, queries_tag));
137 mesh->comm().receive(source_pid,
query, queries_tag);
139 Parallel::Request &
request = reply_requests[p - 1];
141 for (
const auto & q :
query)
143 const Elem * elem =
mesh->elem_ptr(q.first);
144 const unsigned int side = q.second;
148 const Point & face_normal =
_fe_face->get_normals()[0];
151 responses[p - 1].push_back(std::make_pair(elem->id(), side));
154 mesh->comm().send(source_pid, responses[p - 1],
request, replies_tag);
160 Parallel::Status
status(this->
comm().probe(Parallel::any_source, replies_tag));
165 this->
comm().
receive(source_pid, response, replies_tag);
167 for (
const auto & r : response)
169 const Elem * elem =
mesh->elem_ptr(r.first);
170 const unsigned int side = r.second;
173 boundary_info.remove_side(elem, side);
174 for (
const auto & boundary_id : boundary_ids)
175 boundary_info.add_side(elem, side, boundary_id);
179 Parallel::wait(side_requests);
180 Parallel::wait(reply_requests);
184 for (
unsigned int i = 0; i < boundary_ids.size(); ++i)
187 mesh->set_isnt_prepared();
193 const unsigned int side)
const 195 const auto neighbor = elem->neighbor_ptr(side);
196 return (neighbor ==
nullptr) || (elem->subdomain_id() != neighbor->subdomain_id());
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.
SideSetsAroundSubdomainGenerator(const InputParameters ¶meters)
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