www.mooseframework.org
ElementDeleterBase.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 #include "ElementDeleterBase.h"
16 #include "MooseMesh.h"
17 
18 #include "libmesh/remote_elem.h"
19 
20 template <>
23 {
25  params.addParam<BoundaryName>("new_boundary",
26  "optional boundary name to assign to the cut surface");
27  return params;
28 }
29 
31  : MeshModifier(parameters),
32  _assign_boundary(isParamValid("new_boundary")),
33  _boundary_name(_assign_boundary ? getParam<BoundaryName>("new_boundary") : "")
34 {
35 }
36 
37 void
39 {
40  libmesh_assert(this->comm().verify(this->name()));
41 
42  // Check that we have access to the mesh
43  if (!_mesh_ptr)
44  mooseError("_mesh_ptr must be initialized before calling ElementDeleterBase::modify()");
45 
46  MeshBase & mesh = _mesh_ptr->getMesh();
47 
48  // Elements that the deleter will remove
49  std::set<Elem *> deleteable_elems;
50 
51  // First let's figure out which elements need to be deleted
52  for (auto & elem : mesh.element_ptr_range())
53  {
54  if (shouldDelete(elem))
55  deleteable_elems.insert(elem);
56  }
57 
62 #ifdef DEBUG
63  dof_id_type pmax_elem_id = mesh.max_elem_id();
64  mesh.comm().max(pmax_elem_id);
65 
66  for (dof_id_type i = 0; i != pmax_elem_id; ++i)
67  {
68  Elem * elem = mesh.query_elem_ptr(i);
69  bool is_deleteable = elem && deleteable_elems.count(elem);
70 
71  libmesh_assert(mesh.comm().semiverify(elem ? &is_deleteable : libmesh_nullptr));
72  }
73 #endif
74 
75  // Get the BoundaryID from the mesh
76  BoundaryID boundary_id;
77  if (_assign_boundary)
78  boundary_id = _mesh_ptr->getBoundaryIDs({_boundary_name}, true)[0];
79 
80  // Get a reference to our BoundaryInfo object for later use
81  BoundaryInfo & boundary_info = mesh.get_boundary_info();
82 
90  for (auto & elem : deleteable_elems)
91  {
92  // On distributed meshes, we'll need neighbor links to be useable
93  // shortly, so we can't just leave dangling pointers.
94  //
95  // FIXME - this could be made AMR-aware and refactored into
96  // libMesh - roystgnr
97  unsigned int n_sides = elem->n_sides();
98  for (unsigned int n = 0; n != n_sides; ++n)
99  {
100  Elem * neighbor = elem->neighbor_ptr(n);
101  if (!neighbor || neighbor == remote_elem)
102  continue;
103 
104  const unsigned int return_side = neighbor->which_neighbor_am_i(elem);
105 
106  if (neighbor->neighbor_ptr(return_side) == elem)
107  {
108  neighbor->set_neighbor(return_side, nullptr);
109 
110  // assign cut surface boundary
111  if (_assign_boundary)
112  boundary_info.add_side(neighbor, return_side, boundary_id);
113  }
114  }
115 
116  mesh.delete_elem(elem);
117  }
118 
125  if (!mesh.is_serial())
126  {
127  const processor_id_type my_n_proc = mesh.n_processors();
128  const processor_id_type my_proc_id = mesh.processor_id();
129  typedef std::vector<std::pair<dof_id_type, unsigned int>> vec_type;
130  std::vector<vec_type> queries(my_n_proc);
131 
132  // Loop over the elements looking for those with remote neighbors.
133  // The ghost_elements iterators in libMesh need to be updated
134  // before we can use them safely here, so we'll test for
135  // ghost-vs-local manually.
136  for (const auto & elem : mesh.element_ptr_range())
137  {
138  const processor_id_type pid = elem->processor_id();
139  if (pid == my_proc_id)
140  continue;
141 
142  const unsigned int n_sides = elem->n_sides();
143  for (unsigned int n = 0; n != n_sides; ++n)
144  if (elem->neighbor_ptr(n) == remote_elem)
145  queries[pid].push_back(std::make_pair(elem->id(), n));
146  }
147 
148  Parallel::MessageTag queries_tag = mesh.comm().get_unique_tag(42),
149  replies_tag = mesh.comm().get_unique_tag(6 * 9);
150 
151  std::vector<Parallel::Request> query_requests(my_n_proc - 1), reply_requests(my_n_proc - 1);
152 
153  // Make all requests
154  for (processor_id_type p = 0; p != my_n_proc; ++p)
155  {
156  if (p == my_proc_id)
157  continue;
158 
159  Parallel::Request & request = query_requests[p - (p > my_proc_id)];
160 
161  mesh.comm().send(p, queries[p], request, queries_tag);
162  }
163 
164  // Reply to all requests
165  std::vector<vec_type> responses(my_n_proc - 1);
166 
167  for (processor_id_type p = 1; p != my_n_proc; ++p)
168  {
169  vec_type query;
170 
171  Parallel::Status status(mesh.comm().probe(Parallel::any_source, queries_tag));
172  const processor_id_type source_pid = cast_int<processor_id_type>(status.source());
173 
174  mesh.comm().receive(source_pid, query, queries_tag);
175 
176  Parallel::Request & request = reply_requests[p - 1];
177 
178  for (const auto & q : query)
179  {
180  const Elem * elem = mesh.elem_ptr(q.first);
181  const unsigned int side = q.second;
182  const Elem * neighbor = elem->neighbor_ptr(side);
183 
184  if (neighbor == nullptr) // neighboring element was deleted!
185  responses[p - 1].push_back(std::make_pair(elem->id(), side));
186  }
187 
188  mesh.comm().send(source_pid, responses[p - 1], request, replies_tag);
189  }
190 
191  // Process all incoming replies
192  for (processor_id_type p = 1; p != my_n_proc; ++p)
193  {
194  Parallel::Status status(this->comm().probe(Parallel::any_source, replies_tag));
195  const processor_id_type source_pid = cast_int<processor_id_type>(status.source());
196 
197  vec_type response;
198 
199  this->comm().receive(source_pid, response, replies_tag);
200 
201  for (const auto & r : response)
202  {
203  Elem * elem = mesh.elem_ptr(r.first);
204  const unsigned int side = r.second;
205 
206  mooseAssert(elem->neighbor_ptr(side) == remote_elem, "element neighbor != remote_elem");
207 
208  elem->set_neighbor(side, nullptr);
209 
210  // assign cut surface boundary
211  if (_assign_boundary)
212  boundary_info.add_side(elem, side, boundary_id);
213  }
214  }
215 
216  Parallel::wait(query_requests);
217  Parallel::wait(reply_requests);
218  }
219 
220  if (_assign_boundary)
221  {
222  boundary_info.sideset_name(boundary_id) = _boundary_name;
223  boundary_info.nodeset_name(boundary_id) = _boundary_name;
224  }
225 
232  mesh.contract();
234 }
const std::string & name() const
Get the name of the object.
Definition: MooseObject.h:47
const bool _assign_boundary
Assign a boundary name to the cut surface?
InputParameters validParams< ElementDeleterBase >()
void needsPrepareForUse()
If this method is called, we will call libMesh&#39;s prepare_for_use method when we call Moose&#39;s prepare ...
Definition: MooseMesh.C:2098
std::vector< BoundaryID > getBoundaryIDs(const Elem *const elem, const unsigned short int side) const
Returns a vector of boundary IDs for the requested element on the requested side. ...
Definition: MooseMesh.C:1951
MeshModifiers are objects that can modify or add to an existing mesh.
Definition: MeshModifier.h:31
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
MooseMesh * _mesh_ptr
Pointer to the mesh.
Definition: MeshModifier.h:74
virtual void modify() override
Pure virtual modify function MUST be overridden by children classes.
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
Definition: MooseMesh.C:2355
PetscInt n
MPI_Comm comm
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option parameter and a documentation string to the InputParameters object...
void mooseError(Args &&...args) const
Definition: MooseObject.h:80
ElementDeleterBase(const InputParameters &parameters)
virtual bool shouldDelete(const Elem *elem)=0
Method that returns a Boolean indicating whether an element should be removed from the mesh...
InputParameters validParams< MeshModifier >()
Definition: MeshModifier.C:20
boundary_id_type BoundaryID
Definition: MooseTypes.h:75
const BoundaryName _boundary_name
Name of the boundary name to assign to the cut surface.