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