17 #include "libmesh/remote_elem.h" 28 "The primary set of blocks for which to draw a sideset between");
32 "The paired set of blocks for which to draw a sideset between");
34 params.
addClassDescription(
"MeshGenerator that creates a sideset composed of the nodes located " 35 "between two or more subdomains.");
50 std::unique_ptr<MeshBase>
53 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();
74 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));
92 else if (neighbor != NULL)
96 const Point & face_normal = face_normals[0];
102 boundary_info.remove_side(elem, side);
103 for (
const auto & boundary_id : boundary_ids)
104 boundary_info.add_side(elem, side, boundary_id);
110 if (!
mesh->is_serial())
112 const auto queries_tag =
mesh->comm().get_unique_tag(),
113 replies_tag =
mesh->comm().get_unique_tag();
115 std::vector<Parallel::Request> side_requests(my_n_proc - 1), reply_requests(my_n_proc - 1);
123 Parallel::Request &
request = side_requests[p - (p > my_proc_id)];
125 mesh->comm().send(p, queries[p],
request, queries_tag);
129 std::vector<vec_type> responses(my_n_proc - 1);
131 for (
const auto & p :
make_range(uint(1), my_n_proc))
135 Parallel::Status
status(
mesh->comm().probe(Parallel::any_source, queries_tag));
138 mesh->comm().receive(source_pid,
query, queries_tag);
140 Parallel::Request &
request = reply_requests[p - 1];
142 for (
const auto & q :
query)
144 const Elem * elem =
mesh->elem_ptr(q.first);
145 const unsigned int side = q.second;
146 const Elem * neighbor = elem->neighbor_ptr(side);
148 if (neighbor != NULL)
152 const Point & face_normal =
_fe_face->get_normals()[0];
155 responses[p - 1].push_back(std::make_pair(elem->id(), side));
159 mesh->comm().send(source_pid, responses[p - 1],
request, replies_tag);
165 Parallel::Status
status(this->
comm().probe(Parallel::any_source, replies_tag));
170 this->
comm().
receive(source_pid, response, replies_tag);
172 for (
const auto & r : response)
174 const Elem * elem =
mesh->elem_ptr(r.first);
175 const unsigned int side = r.second;
178 boundary_info.remove_side(elem, side);
179 for (
const auto & boundary_id : boundary_ids)
180 boundary_info.add_side(elem, side, boundary_id);
184 Parallel::wait(side_requests);
185 Parallel::wait(reply_requests);
188 for (
const auto & i :
make_range(boundary_ids.size()))
191 mesh->unset_is_prepared();
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...
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