11 #include "libmesh/remote_elem.h" 21 params.
addRequiredParam<MeshGeneratorName>(
"input",
"The mesh we want to modify");
22 params.
addParam<
bool>(
"delete_exteriors",
24 "Whether to delete lower-d elements whose interior parents are deleted");
25 params.
addParam<BoundaryName>(
"new_boundary",
26 "optional boundary name to assign to the cut surface");
33 _input(getMesh(
"input")),
34 _assign_boundary(isParamValid(
"new_boundary")),
35 _delete_exteriors(getParam<bool>(
"delete_exteriors")),
36 _boundary_name(_assign_boundary ? getParam<BoundaryName>(
"new_boundary") :
"")
40 std::unique_ptr<MeshBase>
43 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
46 if (!
mesh->is_prepared())
47 mesh->prepare_for_use();
50 std::set<Elem *> deleteable_elems;
53 for (
auto & elem :
mesh->element_ptr_range())
56 deleteable_elems.insert(elem);
60 for (
auto & elem :
mesh->element_ptr_range())
61 if (elem->dim() <
mesh->mesh_dimension() && deleteable_elems.count(elem->interior_parent()) > 0)
64 deleteable_elems.insert(elem);
66 elem->set_interior_parent(
nullptr);
75 mesh->comm().max(pmax_elem_id);
79 Elem * elem =
mesh->query_elem_ptr(i);
80 bool is_deleteable = elem && deleteable_elems.count(elem);
92 BoundaryInfo & boundary_info =
mesh->get_boundary_info();
101 for (
auto & elem : deleteable_elems)
108 unsigned int n_sides = elem->n_sides();
109 for (
unsigned int n = 0; n != n_sides; ++n)
111 Elem * neighbor = elem->neighbor_ptr(n);
115 const unsigned int return_side = neighbor->which_neighbor_am_i(elem);
117 if (neighbor->neighbor_ptr(return_side) == elem)
119 neighbor->set_neighbor(return_side,
nullptr);
123 boundary_info.add_side(neighbor, return_side, boundary_id);
127 mesh->delete_elem(elem);
136 if (!
mesh->is_serial())
140 typedef std::vector<std::pair<dof_id_type, unsigned int>> vec_type;
141 std::vector<vec_type> queries(my_n_proc);
148 for (
const auto & elem :
mesh->element_ptr_range())
151 if (pid == my_proc_id)
154 const unsigned int n_sides = elem->n_sides();
155 for (
unsigned int n = 0; n != n_sides; ++n)
157 queries[pid].push_back(std::make_pair(elem->id(), n));
161 queries[pid].push_back(std::make_pair(elem->id(), n_sides));
164 const auto queries_tag =
mesh->comm().get_unique_tag(),
165 replies_tag =
mesh->comm().get_unique_tag();
167 std::vector<Parallel::Request> query_requests(my_n_proc - 1), reply_requests(my_n_proc - 1);
175 Parallel::Request &
request = query_requests[p - (p > my_proc_id)];
177 mesh->comm().send(p, queries[p],
request, queries_tag);
181 std::vector<vec_type> responses(my_n_proc - 1);
187 Parallel::Status
status(
mesh->comm().probe(Parallel::any_source, queries_tag));
190 mesh->comm().receive(source_pid,
query, queries_tag);
192 Parallel::Request &
request = reply_requests[p - 1];
194 for (
const auto & q :
query)
196 const Elem * elem =
mesh->elem_ptr(q.first);
197 const unsigned int side = q.second;
198 const Elem * target =
199 (side >= elem->n_sides()) ? elem->interior_parent() : elem->neighbor_ptr(side);
201 if (target ==
nullptr)
202 responses[p - 1].push_back(std::make_pair(elem->id(), side));
205 mesh->comm().send(source_pid, responses[p - 1],
request, replies_tag);
211 Parallel::Status
status(this->
comm().probe(Parallel::any_source, replies_tag));
216 this->
comm().
receive(source_pid, response, replies_tag);
218 for (
const auto & r : response)
220 Elem * elem =
mesh->elem_ptr(r.first);
221 const unsigned int side = r.second;
223 if (side < elem->n_sides())
225 mooseAssert(elem->neighbor_ptr(side) ==
remote_elem,
"element neighbor != remote_elem");
227 elem->set_neighbor(side,
nullptr);
231 boundary_info.add_side(elem, side, boundary_id);
235 mooseAssert(side == elem->n_sides(),
"internal communication error");
236 mooseAssert(elem->interior_parent() ==
remote_elem,
"interior parent != remote_elem");
238 elem->set_interior_parent(
nullptr);
243 Parallel::wait(query_requests);
244 Parallel::wait(reply_requests);
260 mesh->prepare_for_use();
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.
const bool _delete_exteriors
Delete elements whose interior parents are slated for deletion?
static InputParameters validParams()
const bool _assign_boundary
Assign a boundary name to the cut surface?
uint8_t processor_id_type
Status receive(const unsigned int dest_processor_id, T &buf, const MessageTag &tag=any_tag) const
ElementDeletionGeneratorBase(const InputParameters ¶meters)
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()
std::unique_ptr< MeshBase > & _input
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
virtual bool shouldDelete(const Elem *elem)=0
Method that returns a Boolean indicating whether an element should be removed from the mesh...
const BoundaryName _boundary_name
Name of the boundary name to assign to the cut surface.
MeshGenerators are objects that can modify or add to an existing mesh.
const RemoteElem * remote_elem