16 #include "libmesh/remote_elem.h" 25 params.
addRequiredParam<MeshGeneratorName>(
"input",
"The mesh we want to modify");
26 params.
addParam<std::vector<SubdomainName>>(
27 "primary_block",
"The primary set of blocks for which to draw a sideset between");
30 "The primary set of blocks for which to draw a sideset between",
31 "The 'master_block' param is deprecated and will be removed on January 1, 2021. Please use " 32 "the 'primary_block' parameter instead.");
34 "paired_block",
"The paired set of blocks for which to draw a sideset between");
36 "The name of the boundary to create");
37 params.
addClassDescription(
"MeshGenerator that creates a sideset composed of the nodes located " 38 "between two or more subdomains.");
49 std::unique_ptr<MeshBase>
53 ? getParam<std::vector<SubdomainName>>(
"primary_block")
54 :
getParam<std::vector<SubdomainName>>(
"master_block");
56 auto paired_block = getParam<std::vector<SubdomainName>>(
"paired_block");
59 for (
const auto & b : primary_block)
61 paramError(
"primary_block",
"The block '", b,
"' was not found within the mesh");
63 for (
const auto & b : paired_block)
65 paramError(
"paired_block",
"The block '", b,
"' was not found within the mesh");
67 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
70 if (!
mesh->is_prepared())
71 mesh->find_neighbors();
73 std::vector<subdomain_id_type> vec_primary_ids =
75 std::set<subdomain_id_type> primary_ids(vec_primary_ids.begin(), vec_primary_ids.end());
77 std::vector<subdomain_id_type> vec_paired_ids =
79 std::set<subdomain_id_type> paired_ids(vec_paired_ids.begin(), vec_paired_ids.end());
81 std::vector<BoundaryName> boundary_names = getParam<std::vector<BoundaryName>>(
"new_boundary");
82 std::vector<boundary_id_type> boundary_ids =
86 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
92 typedef std::vector<std::pair<dof_id_type, unsigned int>> vec_type;
93 std::vector<vec_type> queries(my_n_proc);
95 for (
const auto & elem :
mesh->active_element_ptr_range())
100 if (primary_ids.count(curr_subdomain) == 0)
103 for (
unsigned int side = 0; side < elem->n_sides(); side++)
105 const Elem * neighbor = elem->neighbor_ptr(side);
112 queries[elem->processor_id()].push_back(std::make_pair(elem->id(), side));
114 else if (neighbor != NULL && paired_ids.count(neighbor->subdomain_id()) > 0)
117 for (
const auto & boundary_id : boundary_ids)
118 boundary_info.add_side(elem, side, boundary_id);
122 if (!
mesh->is_serial())
124 const auto queries_tag =
mesh->comm().get_unique_tag(),
125 replies_tag =
mesh->comm().get_unique_tag();
127 std::vector<Parallel::Request> side_requests(my_n_proc - 1), reply_requests(my_n_proc - 1);
135 Parallel::Request &
request = side_requests[p - (p > my_proc_id)];
137 mesh->comm().send(p, queries[p],
request, queries_tag);
141 std::vector<vec_type> responses(my_n_proc - 1);
147 Parallel::Status
status(
mesh->comm().probe(Parallel::any_source, queries_tag));
150 mesh->comm().receive(source_pid,
query, queries_tag);
152 Parallel::Request &
request = reply_requests[p - 1];
154 for (
const auto & q :
query)
156 const Elem * elem =
mesh->elem_ptr(q.first);
157 const unsigned int side = q.second;
158 const Elem * neighbor = elem->neighbor_ptr(side);
160 if (neighbor != NULL && paired_ids.count(neighbor->subdomain_id()) > 0)
162 responses[p - 1].push_back(std::make_pair(elem->id(), side));
166 mesh->comm().send(source_pid, responses[p - 1],
request, replies_tag);
172 Parallel::Status
status(this->
comm().probe(Parallel::any_source, replies_tag));
177 this->
comm().
receive(source_pid, response, replies_tag);
179 for (
const auto & r : response)
181 const Elem * elem =
mesh->elem_ptr(r.first);
182 const unsigned int side = r.second;
184 for (
const auto & boundary_id : boundary_ids)
185 boundary_info.add_side(elem, side, boundary_id);
189 Parallel::wait(side_requests);
190 Parallel::wait(reply_requests);
193 for (
unsigned int i = 0; i < boundary_ids.size(); ++i)
194 boundary_info.sideset_name(boundary_ids[i]) = boundary_names[i];
196 mesh->set_isnt_prepared();
static InputParameters validParams()
const Parallel::Communicator & comm() const
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.
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.
bool isParamValid(const std::string &name) const
Test if the supplied parameter is valid.
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
const T & getParam(const std::string &name) const
Retrieve a parameter for the object.
bool hasSubdomainName(MeshBase &input_mesh, const SubdomainName &name)
Whether a particular subdomain name exists in the mesh.
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.
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 ...
static InputParameters validParams()
SideSetsBetweenSubdomainsGenerator(const InputParameters ¶meters)
MeshGenerator that creates a sideset composed of the nodes located between two or more subdomains...
MeshGenerators are objects that can modify or add to an existing mesh.
std::unique_ptr< MeshBase > & _input
const RemoteElem * remote_elem