16 #include "libmesh/remote_elem.h" 27 "The primary set of blocks for which to draw a sideset between");
31 "The paired set of blocks for which to draw a sideset between");
33 params.
addClassDescription(
"MeshGenerator that creates a sideset composed of the nodes located " 34 "between two or more subdomains.");
49 std::unique_ptr<MeshBase>
52 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
57 std::vector<boundary_id_type> boundary_ids =
61 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
67 typedef std::vector<std::pair<dof_id_type, unsigned int>> vec_type;
68 std::vector<vec_type> queries(my_n_proc);
71 const std::vector<Point> & face_normals =
_fe_face->get_normals();
73 for (
const auto & elem :
mesh->active_element_ptr_range())
79 for (
const auto & side :
make_range(elem->n_sides()))
81 const Elem * neighbor = elem->neighbor_ptr(side);
88 queries[elem->processor_id()].push_back(std::make_pair(elem->id(), side));
90 else if (neighbor != NULL)
94 const Point & face_normal = face_normals[0];
100 boundary_info.remove_side(elem, side);
101 for (
const auto & boundary_id : boundary_ids)
102 boundary_info.add_side(elem, side, boundary_id);
108 if (!
mesh->is_serial())
110 const auto queries_tag =
mesh->comm().get_unique_tag(),
111 replies_tag =
mesh->comm().get_unique_tag();
113 std::vector<Parallel::Request> side_requests(my_n_proc - 1), reply_requests(my_n_proc - 1);
121 Parallel::Request &
request = side_requests[p - (p > my_proc_id)];
123 mesh->comm().send(p, queries[p],
request, queries_tag);
127 std::vector<vec_type> responses(my_n_proc - 1);
129 for (
const auto & p :
make_range(uint(1), my_n_proc))
133 Parallel::Status
status(
mesh->comm().probe(Parallel::any_source, queries_tag));
136 mesh->comm().receive(source_pid,
query, queries_tag);
138 Parallel::Request &
request = reply_requests[p - 1];
140 for (
const auto & q :
query)
142 const Elem * elem =
mesh->elem_ptr(q.first);
143 const unsigned int side = q.second;
144 const Elem * neighbor = elem->neighbor_ptr(side);
146 if (neighbor != NULL)
150 const Point & face_normal =
_fe_face->get_normals()[0];
153 responses[p - 1].push_back(std::make_pair(elem->id(), side));
157 mesh->comm().send(source_pid, responses[p - 1],
request, replies_tag);
163 Parallel::Status
status(this->
comm().probe(Parallel::any_source, replies_tag));
168 this->
comm().
receive(source_pid, response, replies_tag);
170 for (
const auto & r : response)
172 const Elem * elem =
mesh->elem_ptr(r.first);
173 const unsigned int side = r.second;
176 boundary_info.remove_side(elem, side);
177 for (
const auto & boundary_id : boundary_ids)
178 boundary_info.add_side(elem, side, boundary_id);
182 Parallel::wait(side_requests);
183 Parallel::wait(reply_requests);
186 for (
const auto & i :
make_range(boundary_ids.size()))
189 mesh->set_isnt_prepared();
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.
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...
static InputParameters validParams()
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.
registerMooseObject("MooseApp", SideSetsBetweenSubdomainsGenerator)
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()
SideSetsBetweenSubdomainsGenerator(const InputParameters ¶meters)
const bool _check_subdomains
whether to check subdomain ids of the element in the (element, side, boundary id) tuple when adding s...
MeshGenerator that creates a sideset composed of the nodes located between two or more subdomains...
IntRange< T > make_range(T beg, T end)
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