unstructured_mesh.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 // C++ includes
21 #include <fstream>
22 #include <sstream>
23 #include <iomanip>
24 #include <unordered_map>
25 
26 // C includes
27 #include <sys/types.h> // for pid_t
28 #include <unistd.h> // for getpid(), unlink()
29 
30 // Local includes
31 #include "libmesh/boundary_info.h"
35 #include "libmesh/elem.h"
36 #include "libmesh/mesh_tools.h" // For n_levels
37 #include "libmesh/parallel.h"
38 #include "libmesh/remote_elem.h"
39 
40 // For most I/O
41 #include "libmesh/namebased_io.h"
42 
43 
44 
45 namespace libMesh
46 {
47 
48 
49 // ------------------------------------------------------------
50 // UnstructuredMesh class member functions
52  unsigned char d) :
53  MeshBase (comm_in,d)
54 {
55  libmesh_assert (libMesh::initialized());
56 }
57 
58 
59 
60 #ifndef LIBMESH_DISABLE_COMMWORLD
61 #ifdef LIBMESH_ENABLE_DEPRECATED
63  MeshBase (d)
64 {
65  libmesh_deprecated();
66  libmesh_assert (libMesh::initialized());
67 }
68 #endif
69 #endif
70 
71 
72 
74  const bool skip_find_neighbors)
75 {
76  LOG_SCOPE("copy_nodes_and_elements()", "UnstructuredMesh");
77 
78  // We expect to have at least as many processors as the other mesh
79  // is partitioned into, so that our partitioning will still be
80  // consistent afterwards.
81  libmesh_assert_greater_equal (_n_parts, other_mesh._n_parts);
82 
83  // We're assuming our subclass data needs no copy
84  libmesh_assert_equal_to (_is_prepared, other_mesh._is_prepared);
85 
86  // We're assuming the other mesh has proper element number ordering,
87  // so that we add parents before their children.
88 #ifdef DEBUG
90 #endif
91 
92  //Copy in Nodes
93  {
94  //Preallocate Memory if necessary
95  this->reserve_nodes(other_mesh.n_nodes());
96 
97  for (const auto & oldn : other_mesh.node_ptr_range())
98  {
99  // Add new nodes in old node Point locations
100 #ifdef LIBMESH_ENABLE_UNIQUE_ID
101  Node * newn =
102 #endif
103  this->add_point(*oldn, oldn->id(), oldn->processor_id());
104 
105 #ifdef LIBMESH_ENABLE_UNIQUE_ID
106  newn->set_unique_id() = oldn->unique_id();
107 #endif
108  }
109  }
110 
111  //Copy in Elements
112  {
113  //Preallocate Memory if necessary
114  this->reserve_elem(other_mesh.n_elem());
115 
116  // Declare a map linking old and new elements, needed to copy the neighbor lists
117  typedef std::unordered_map<const Elem *, Elem *> map_type;
118  map_type old_elems_to_new_elems;
119 
120  // Loop over the elements
121  for (const auto & old : other_mesh.element_ptr_range())
122  {
123  // Build a new element
124  Elem * newparent = old->parent() ?
125  this->elem_ptr(old->parent()->id()) : libmesh_nullptr;
126  std::unique_ptr<Elem> ap = Elem::build(old->type(), newparent);
127  Elem * el = ap.release();
128 
129  el->subdomain_id() = old->subdomain_id();
130 
131  for (auto s : old->side_index_range())
132  if (old->neighbor_ptr(s) == remote_elem)
133  el->set_neighbor(s, const_cast<RemoteElem *>(remote_elem));
134 
135 #ifdef LIBMESH_ENABLE_AMR
136  if (old->has_children())
137  for (unsigned int c = 0, nc = old->n_children(); c != nc; ++c)
138  if (old->child_ptr(c) == remote_elem)
139  el->add_child(const_cast<RemoteElem *>(remote_elem), c);
140 
141  //Create the parent's child pointers if necessary
142  if (newparent)
143  {
144  unsigned int oldc = old->parent()->which_child_am_i(old);
145  newparent->add_child(el, oldc);
146  }
147 
148  // Copy the refinement flags
149  el->set_refinement_flag(old->refinement_flag());
150 
151  // Use hack_p_level since we may not have sibling elements
152  // added yet
153  el->hack_p_level(old->p_level());
154 
155  el->set_p_refinement_flag(old->p_refinement_flag());
156 #endif // #ifdef LIBMESH_ENABLE_AMR
157 
158  //Assign all the nodes
159  for (auto i : el->node_index_range())
160  el->set_node(i) = this->node_ptr(old->node_id(i));
161 
162  // And start it off in the same subdomain
163  el->processor_id() = old->processor_id();
164 
165  // Give it the same element and unique ids
166  el->set_id(old->id());
167 
168 #ifdef LIBMESH_ENABLE_UNIQUE_ID
169  el->set_unique_id() = old->unique_id();
170 #endif
171 
172  //Hold onto it
173  if (!skip_find_neighbors)
174  {
175  this->add_elem(el);
176  }
177  else
178  {
179  Elem * new_el = this->add_elem(el);
180  old_elems_to_new_elems[old] = new_el;
181  }
182 
183  // Add the link between the original element and this copy to the map
184  if (skip_find_neighbors)
185  old_elems_to_new_elems[old] = el;
186  }
187 
188  // Loop (again) over the elements to fill in the neighbors
189  if (skip_find_neighbors)
190  {
191  for (const auto & old_elem : other_mesh.element_ptr_range())
192  {
193  Elem * new_elem = old_elems_to_new_elems[old_elem];
194  for (auto s : old_elem->side_index_range())
195  {
196  const Elem * old_neighbor = old_elem->neighbor_ptr(s);
197  Elem * new_neighbor = old_elems_to_new_elems[old_neighbor];
198  new_elem->set_neighbor(s, new_neighbor);
199  }
200  }
201  }
202  }
203 
204  //Finally prepare the new Mesh for use. Keep the same numbering and
205  //partitioning for now.
206  this->allow_renumbering(false);
207  this->allow_remote_element_removal(false);
208  this->skip_partitioning(true);
209 
210  this->prepare_for_use(false, skip_find_neighbors);
211 
212  //But in the long term, use the same renumbering and partitioning
213  //policies as our source mesh.
214  this->allow_renumbering(other_mesh.allow_renumbering());
216  this->skip_partitioning(other_mesh.skip_partitioning());
217 }
218 
219 
220 
222 {
223  // this->clear (); // Nothing to clear at this level
224 
225  libmesh_exceptionless_assert (!libMesh::closed());
226 }
227 
228 
229 
230 
231 
232 void UnstructuredMesh::find_neighbors (const bool reset_remote_elements,
233  const bool reset_current_list)
234 {
235  // We might actually want to run this on an empty mesh
236  // (e.g. the boundary mesh for a nonexistent bcid!)
237  // libmesh_assert_not_equal_to (this->n_nodes(), 0);
238  // libmesh_assert_not_equal_to (this->n_elem(), 0);
239 
240  // This function must be run on all processors at once
241  parallel_object_only();
242 
243  LOG_SCOPE("find_neighbors()", "Mesh");
244 
245  const element_iterator el_end = this->elements_end();
246 
247  //TODO:[BSK] This should be removed later?!
248  if (reset_current_list)
249  for (element_iterator el = this->elements_begin(); el != el_end; ++el)
250  {
251  Elem * e = *el;
252  for (auto s : e->side_index_range())
253  if (e->neighbor_ptr(s) != remote_elem ||
254  reset_remote_elements)
256  }
257 
258  // Find neighboring elements by first finding elements
259  // with identical side keys and then check to see if they
260  // are neighbors
261  {
262  // data structures -- Use the hash_multimap if available
263  typedef unsigned int key_type;
264  typedef std::pair<Elem *, unsigned char> val_type;
265  typedef std::pair<key_type, val_type> key_val_pair;
266 
267  typedef std::unordered_multimap<key_type, val_type> map_type;
268 
269  // A map from side keys to corresponding elements & side numbers
270  map_type side_to_elem_map;
271 
272 
273 
274  for (element_iterator el = this->elements_begin(); el != el_end; ++el)
275  {
276  Elem * element = *el;
277 
278  for (auto ms : element->side_index_range())
279  {
280  next_side:
281  // If we haven't yet found a neighbor on this side, try.
282  // Even if we think our neighbor is remote, that
283  // information may be out of date.
284  if (element->neighbor_ptr(ms) == libmesh_nullptr ||
285  element->neighbor_ptr(ms) == remote_elem)
286  {
287  // Get the key for the side of this element
288  const unsigned int key = element->key(ms);
289 
290  // Look for elements that have an identical side key
291  std::pair <map_type::iterator, map_type::iterator>
292  bounds = side_to_elem_map.equal_range(key);
293 
294  // May be multiple keys, check all the possible
295  // elements which _might_ be neighbors.
296  if (bounds.first != bounds.second)
297  {
298  // Get the side for this element
299  const std::unique_ptr<Elem> my_side(element->side_ptr(ms));
300 
301  // Look at all the entries with an equivalent key
302  while (bounds.first != bounds.second)
303  {
304  // Get the potential element
305  Elem * neighbor = bounds.first->second.first;
306 
307  // Get the side for the neighboring element
308  const unsigned int ns = bounds.first->second.second;
309  const std::unique_ptr<Elem> their_side(neighbor->side_ptr(ns));
310  //libmesh_assert(my_side.get());
311  //libmesh_assert(their_side.get());
312 
313  // If found a match with my side
314  //
315  // We need special tests here for 1D:
316  // since parents and children have an equal
317  // side (i.e. a node), we need to check
318  // ns != ms, and we also check level() to
319  // avoid setting our neighbor pointer to
320  // any of our neighbor's descendants
321  if ((*my_side == *their_side) &&
322  (element->level() == neighbor->level()) &&
323  ((element->dim() != 1) || (ns != ms)))
324  {
325  // So share a side. Is this a mixed pair
326  // of subactive and active/ancestor
327  // elements?
328  // If not, then we're neighbors.
329  // If so, then the subactive's neighbor is
330 
331  if (element->subactive() ==
332  neighbor->subactive())
333  {
334  // an element is only subactive if it has
335  // been coarsened but not deleted
336  element->set_neighbor (ms,neighbor);
337  neighbor->set_neighbor(ns,element);
338  }
339  else if (element->subactive())
340  {
341  element->set_neighbor(ms,neighbor);
342  }
343  else if (neighbor->subactive())
344  {
345  neighbor->set_neighbor(ns,element);
346  }
347  side_to_elem_map.erase (bounds.first);
348 
349  // get out of this nested crap
350  goto next_side;
351  }
352 
353  ++bounds.first;
354  }
355  }
356 
357  // didn't find a match...
358  // Build the map entry for this element
359  key_val_pair kvp;
360 
361  kvp.first = key;
362  kvp.second.first = element;
363  kvp.second.second = ms;
364  side_to_elem_map.insert (kvp);
365  }
366  }
367  }
368  }
369 
370 #ifdef LIBMESH_ENABLE_AMR
371 
399  const unsigned int n_levels = MeshTools::n_levels(*this);
400  for (unsigned int level = 1; level < n_levels; ++level)
401  {
402  element_iterator end = this->level_elements_end(level);
403  for (element_iterator el = this->level_elements_begin(level);
404  el != end; ++el)
405  {
406  Elem * current_elem = *el;
407  libmesh_assert(current_elem);
408  Elem * parent = current_elem->parent();
409  libmesh_assert(parent);
410  const unsigned int my_child_num = parent->which_child_am_i(current_elem);
411 
412  for (auto s : current_elem->side_index_range())
413  {
414  if (current_elem->neighbor_ptr(s) == libmesh_nullptr ||
415  (current_elem->neighbor_ptr(s) == remote_elem &&
416  parent->is_child_on_side(my_child_num, s)))
417  {
418  Elem * neigh = parent->neighbor_ptr(s);
419 
420  // If neigh was refined and had non-subactive children
421  // made remote earlier, then our current elem should
422  // actually have one of those remote children as a
423  // neighbor
424  if (neigh &&
425  (neigh->ancestor() ||
426  // If neigh has subactive children which should have
427  // matched as neighbors of the current element but
428  // did not, then those likewise must be remote
429  // children.
430  (current_elem->subactive() && neigh->has_children() &&
431  (neigh->level()+1) == current_elem->level())))
432  {
433 #ifdef DEBUG
434  // Let's make sure that "had children made remote"
435  // situation is actually the case
436  libmesh_assert(neigh->has_children());
437  bool neigh_has_remote_children = false;
438  for (auto & child : neigh->child_ref_range())
439  if (&child == remote_elem)
440  neigh_has_remote_children = true;
441  libmesh_assert(neigh_has_remote_children);
442 
443  // And let's double-check that we don't have
444  // a remote_elem neighboring an active local element
445  if (current_elem->active())
446  libmesh_assert_not_equal_to (current_elem->processor_id(),
447  this->processor_id());
448 #endif // DEBUG
449  neigh = const_cast<RemoteElem *>(remote_elem);
450  }
451  // If neigh and current_elem are more than one level
452  // apart, figuring out whether we have a remote
453  // neighbor here becomes much harder.
454  else if (neigh && (current_elem->subactive() &&
455  neigh->has_children()))
456  {
457  // Find the deepest descendant of neigh which
458  // we could consider for a neighbor. If we run
459  // out of neigh children, then that's our
460  // neighbor. If we find a potential neighbor
461  // with remote_children and we don't find any
462  // potential neighbors among its non-remote
463  // children, then our neighbor must be remote.
464  while (neigh != remote_elem &&
465  neigh->has_children())
466  {
467  bool found_neigh = false;
468  for (unsigned int c = 0, nc = neigh->n_children();
469  !found_neigh && c != nc; ++c)
470  {
471  Elem * child = neigh->child_ptr(c);
472  if (child == remote_elem)
473  continue;
474  for (auto ncn : child->neighbor_ptr_range())
475  {
476  if (ncn != remote_elem &&
477  ncn->is_ancestor_of(current_elem))
478  {
479  neigh = ncn;
480  found_neigh = true;
481  break;
482  }
483  }
484  }
485  if (!found_neigh)
486  neigh = const_cast<RemoteElem *>(remote_elem);
487  }
488  }
489  current_elem->set_neighbor(s, neigh);
490 #ifdef DEBUG
491  if (neigh != libmesh_nullptr && neigh != remote_elem)
492  // We ignore subactive elements here because
493  // we don't care about neighbors of subactive element.
494  if ((!neigh->active()) && (!current_elem->subactive()))
495  {
496  libMesh::err << "On processor " << this->processor_id()
497  << std::endl;
498  libMesh::err << "Bad element ID = " << current_elem->id()
499  << ", Side " << s << ", Bad neighbor ID = " << neigh->id() << std::endl;
500  libMesh::err << "Bad element proc_ID = " << current_elem->processor_id()
501  << ", Bad neighbor proc_ID = " << neigh->processor_id() << std::endl;
502  libMesh::err << "Bad element size = " << current_elem->hmin()
503  << ", Bad neighbor size = " << neigh->hmin() << std::endl;
504  libMesh::err << "Bad element center = " << current_elem->centroid()
505  << ", Bad neighbor center = " << neigh->centroid() << std::endl;
506  libMesh::err << "ERROR: "
507  << (current_elem->active()?"Active":"Ancestor")
508  << " Element at level "
509  << current_elem->level() << std::endl;
510  libMesh::err << "with "
511  << (parent->active()?"active":
512  (parent->subactive()?"subactive":"ancestor"))
513  << " parent share "
514  << (neigh->subactive()?"subactive":"ancestor")
515  << " neighbor at level " << neigh->level()
516  << std::endl;
517  NameBasedIO(*this).write ("bad_mesh.gmv");
518  libmesh_error_msg("Problematic mesh written to bad_mesh.gmv.");
519  }
520 #endif // DEBUG
521  }
522  }
523 
524  // We can skip to the next element if we're full-dimension
525  // and therefore don't have any interior parents
526  if (current_elem->dim() >= LIBMESH_DIM)
527  continue;
528 
529  // We have no interior parents unless we can find one later
530  current_elem->set_interior_parent(libmesh_nullptr);
531 
532  Elem * pip = parent->interior_parent();
533 
534  if (!pip)
535  continue;
536 
537  // If there's no interior_parent children, whether due to a
538  // remote element or a non-conformity, then there's no
539  // children to search.
540  if (pip == remote_elem || pip->active())
541  {
542  current_elem->set_interior_parent(pip);
543  continue;
544  }
545 
546  // For node comparisons we'll need a sensible tolerance
547  Real node_tolerance = current_elem->hmin() * TOLERANCE;
548 
549  // Otherwise our interior_parent should be a child of our
550  // parent's interior_parent.
551  for (auto & child : pip->child_ref_range())
552  {
553  // If we have a remote_elem, that might be our
554  // interior_parent. We'll set it provisionally now and
555  // keep trying to find something better.
556  if (&child == remote_elem)
557  {
558  current_elem->set_interior_parent
559  (const_cast<RemoteElem *>(remote_elem));
560  continue;
561  }
562 
563  bool child_contains_our_nodes = true;
564  for (auto & n : current_elem->node_ref_range())
565  {
566  bool child_contains_this_node = false;
567  for (auto & cn : child.node_ref_range())
568  if (cn.absolute_fuzzy_equals
569  (n, node_tolerance))
570  {
571  child_contains_this_node = true;
572  break;
573  }
574  if (!child_contains_this_node)
575  {
576  child_contains_our_nodes = false;
577  break;
578  }
579  }
580  if (child_contains_our_nodes)
581  {
582  current_elem->set_interior_parent(&child);
583  break;
584  }
585  }
586 
587  // We should have found *some* interior_parent at this
588  // point, whether semilocal or remote.
589  libmesh_assert(current_elem->interior_parent());
590  }
591  }
592 
593 #endif // AMR
594 
595 
596 #ifdef DEBUG
598  !reset_remote_elements);
600 #endif
601 }
602 
603 
604 
605 void UnstructuredMesh::read (const std::string & name,
606  void *,
607  bool skip_renumber_nodes_and_elements,
608  bool skip_find_neighbors)
609 {
610  // Set the skip_renumber_nodes_and_elements flag on all processors
611  // if necessary.
612  // This ensures that renumber_nodes_and_elements is *not* called
613  // during prepare_for_use() for certain types of mesh files.
614  // This is required in cases where there is an associated solution
615  // file which expects a certain ordering of the nodes.
616  if (name.rfind(".gmv") + 4 == name.size())
617  this->allow_renumbering(false);
618 
619  NameBasedIO(*this).read(name);
620 
621  if (skip_renumber_nodes_and_elements)
622  {
623  // Use MeshBase::allow_renumbering() yourself instead.
624  libmesh_deprecated();
625  this->allow_renumbering(false);
626  }
627 
628  // Done reading the mesh. Now prepare it for use.
629  this->prepare_for_use(/*skip_renumber (deprecated)*/ false,
630  skip_find_neighbors);
631 }
632 
633 
634 
635 void UnstructuredMesh::write (const std::string & name)
636 {
637  LOG_SCOPE("write()", "Mesh");
638 
639  NameBasedIO(*this).write(name);
640 }
641 
642 
643 
644 void UnstructuredMesh::write (const std::string & name,
645  const std::vector<Number> & v,
646  const std::vector<std::string> & vn)
647 {
648  LOG_SCOPE("write()", "Mesh");
649 
650  NameBasedIO(*this).write_nodal_data(name, v, vn);
651 }
652 
653 
654 
655 
656 
658  const processor_id_type pid) const
659 {
660 
661  // Issue a warning if the number the number of processors
662  // currently available is less that that requested for
663  // partitioning. This is not necessarily an error since
664  // you may run on one processor and still partition the
665  // mesh into several partitions.
666 #ifdef DEBUG
667  if (this->n_processors() < pid)
668  {
669  libMesh::out << "WARNING: You are creating a "
670  << "mesh for a processor id (="
671  << pid
672  << ") greater than "
673  << "the number of processors available for "
674  << "the calculation. (="
675  << this->n_processors()
676  << ")."
677  << std::endl;
678  }
679 #endif
680 
681  // Create iterators to loop over the list of elements
682  // const_active_pid_elem_iterator it(this->elements_begin(), pid);
683  // const const_active_pid_elem_iterator it_end(this->elements_end(), pid);
684 
686  const const_element_iterator it_end = this->active_pid_elements_end(pid);
687 
688  this->create_submesh (pid_mesh, it, it_end);
689 }
690 
691 
692 
693 
694 
695 
696 
699  const const_element_iterator & it_end) const
700 {
701  // Just in case the subdomain_mesh already has some information
702  // in it, get rid of it.
703  new_mesh.clear();
704 
705  // If we're not serial, our submesh isn't either.
706  // There are no remote elements to delete on an empty mesh, but
707  // calling the method to do so marks the mesh as parallel.
708  if (!this->is_serial())
709  new_mesh.delete_remote_elements();
710 
711  // Fail if (*this == new_mesh), we cannot create a submesh inside ourself!
712  // This may happen if the user accidentally passes the original mesh into
713  // this function! We will check this by making sure we did not just
714  // clear ourself.
715  libmesh_assert_not_equal_to (this->n_nodes(), 0);
716  libmesh_assert_not_equal_to (this->n_elem(), 0);
717 
718  // Container to catch boundary IDs handed back by BoundaryInfo
719  std::vector<boundary_id_type> bc_ids;
720 
721  for (; it != it_end; ++it)
722  {
723  const Elem * old_elem = *it;
724 
725  // Add an equivalent element type to the new_mesh.
726  // Copy ids for this element.
727  Elem * new_elem = Elem::build(old_elem->type()).release();
728  new_elem->set_id() = old_elem->id();
729 #ifdef LIBMESH_ENABLE_UNIQUE_ID
730  new_elem->set_unique_id() = old_elem->unique_id();
731 #endif
732  new_elem->subdomain_id() = old_elem->subdomain_id();
733  new_elem->processor_id() = old_elem->processor_id();
734 
735  new_mesh.add_elem (new_elem);
736 
737  libmesh_assert(new_elem);
738 
739  // Loop over the nodes on this element.
740  for (auto n : old_elem->node_index_range())
741  {
742  const dof_id_type this_node_id = old_elem->node_id(n);
743 
744  // Add this node to the new mesh if it's not there already
745  if (!new_mesh.query_node_ptr(this_node_id))
746  {
747 #ifdef LIBMESH_ENABLE_UNIQUE_ID
748  Node *newn =
749 #endif
750  new_mesh.add_point (old_elem->point(n),
751  this_node_id,
752  old_elem->node_ptr(n)->processor_id());
753 
754 #ifdef LIBMESH_ENABLE_UNIQUE_ID
755  newn->set_unique_id() = old_elem->node_ptr(n)->unique_id();
756 #endif
757  }
758 
759  // Define this element's connectivity on the new mesh
760  new_elem->set_node(n) = new_mesh.node_ptr(this_node_id);
761  }
762 
763  // Maybe add boundary conditions for this element
764  for (auto s : old_elem->side_index_range())
765  {
766  this->get_boundary_info().boundary_ids(old_elem, s, bc_ids);
767  new_mesh.get_boundary_info().add_side (new_elem, s, bc_ids);
768  }
769  } // end loop over elements
770 
771  // Prepare the new_mesh for use
772  new_mesh.prepare_for_use(/*skip_renumber =*/false);
773 }
774 
775 
776 
777 #ifdef LIBMESH_ENABLE_AMR
779 {
780  LOG_SCOPE ("contract()", "Mesh");
781 
782  // Flag indicating if this call actually changes the mesh
783  bool mesh_changed = false;
784 
787 
788 #ifdef DEBUG
789  for ( ; in != end; ++in)
790  if (*in != libmesh_nullptr)
791  {
792  Elem * el = *in;
793  libmesh_assert(el->active() || el->subactive() || el->ancestor());
794  }
795  in = elements_begin();
796 #endif
797 
798  // Loop over the elements.
799  for ( ; in != end; ++in)
800  if (*in != libmesh_nullptr)
801  {
802  Elem * el = *in;
803 
804  // Delete all the subactive ones
805  if (el->subactive())
806  {
807  // No level-0 element should be subactive.
808  // Note that we CAN'T test elem->level(), as that
809  // touches elem->parent()->dim(), and elem->parent()
810  // might have already been deleted!
811  libmesh_assert(el->parent());
812 
813  // Delete the element
814  // This just sets a pointer to NULL, and doesn't
815  // invalidate any iterators
816  this->delete_elem(el);
817 
818  // the mesh has certainly changed
819  mesh_changed = true;
820  }
821  else
822  {
823  // Compress all the active ones
824  if (el->active())
825  el->contract();
826  else
827  libmesh_assert (el->ancestor());
828  }
829  }
830 
831  // Strip any newly-created NULL voids out of the element array
833 
834  // FIXME: Need to understand why deleting subactive children
835  // invalidates the point locator. For now we will clear it explicitly
836  this->clear_point_locator();
837 
838  // Allow our GhostingFunctor objects to reinit if necessary.
839  std::set<GhostingFunctor *>::iterator gf_it = this->ghosting_functors_begin();
840  const std::set<GhostingFunctor *>::iterator gf_end = this->ghosting_functors_end();
841  for (; gf_it != gf_end; ++gf_it)
842  {
843  GhostingFunctor *gf = *gf_it;
844  libmesh_assert(gf);
845  gf->mesh_reinit();
846  }
847 
848  return mesh_changed;
849 }
850 #endif // #ifdef LIBMESH_ENABLE_AMR
851 
852 } // namespace libMesh
std::string name(const ElemQuality q)
Definition: elem_quality.C:39
bool ancestor() const
Definition: elem.C:1463
virtual void read(const std::string &mesh_file) libmesh_override
Definition: namebased_io.C:62
bool has_children() const
Definition: elem.h:2296
bool closed()
Definition: libmesh.C:280
const BoundaryInfo & get_boundary_info() const
Definition: mesh_base.h:118
unique_id_type & set_unique_id()
Definition: dof_object.h:662
virtual void reserve_nodes(const dof_id_type nn)=0
virtual void read(const std::string &name, void *mesh_data=libmesh_nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false) libmesh_override
Used by ParallelMesh to represent an Elem owned by another processor.
Definition: remote_elem.h:44
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:1942
A geometric point in (x,y,z) space associated with a DOF.
Definition: node.h:52
void create_pid_mesh(UnstructuredMesh &pid_mesh, const processor_id_type pid) const
bool subactive() const
Definition: elem.h:2276
virtual bool is_serial() const
Definition: mesh_base.h:141
void libmesh_assert_valid_amr_interior_parents(const MeshBase &mesh)
Definition: mesh_tools.C:1133
bool active() const
Definition: elem.h:2258
virtual ElemType type() const =0
virtual element_iterator level_elements_begin(unsigned int level)=0
virtual void copy_nodes_and_elements(const UnstructuredMesh &other_mesh, const bool skip_find_neighbors=false)
void allow_renumbering(bool allow)
Definition: mesh_base.h:750
bool skip_partitioning() const
Definition: mesh_base.h:776
void skip_partitioning(bool skip)
Definition: mesh_base.h:775
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2084
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2066
const Elem * parent() const
Definition: elem.h:2347
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) libmesh_override
Definition: namebased_io.C:425
processor_id_type n_processors() const
const Elem * interior_parent() const
Definition: elem.C:843
The base class for all geometric element types.
Definition: elem.h:90
virtual Real hmin() const
Definition: elem.C:350
uint8_t processor_id_type
Definition: id_types.h:99
void add_child(Elem *elem)
Definition: elem.C:1497
const class libmesh_nullptr_t libmesh_nullptr
virtual const Node * node_ptr(const dof_id_type i) const =0
static const Real TOLERANCE
IterBase * end
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true) libmesh_override
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
void set_interior_parent(Elem *p)
Definition: elem.C:895
Base class for Mesh.
Definition: mesh_base.h:69
SimpleRange< ChildRefIter > child_ref_range()
Definition: elem.h:1700
dof_id_type & set_id()
Definition: dof_object.h:641
std::set< GhostingFunctor * >::const_iterator ghosting_functors_end() const
Definition: mesh_base.h:805
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:1968
std::vector< boundary_id_type > boundary_ids(const Node *node) const
void create_submesh(UnstructuredMesh &new_mesh, const_element_iterator &it, const const_element_iterator &it_end) const
virtual element_iterator elements_begin()=0
virtual element_iterator level_elements_end(unsigned int level)=0
unsigned int _n_parts
Definition: mesh_base.h:1343
void allow_remote_element_removal(bool allow)
Definition: mesh_base.h:759
virtual void write(const std::string &mesh_file) libmesh_override
Definition: namebased_io.C:279
virtual void delete_elem(Elem *e)=0
virtual SimpleRange< element_iterator > element_ptr_range()=0
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1875
bool is_ancestor_of(const Elem *descendant) const
Definition: elem.h:2326
virtual element_iterator active_pid_elements_begin(processor_id_type proc_id)=0
Base class for Replicated and Distributed meshes.
virtual Elem * add_elem(Elem *e)=0
virtual element_iterator elements_end()=0
unsigned int n_levels(const MeshBase &mesh)
Definition: mesh_tools.C:603
virtual SimpleRange< node_iterator > node_ptr_range()=0
virtual bool contract() libmesh_override
virtual const Node * query_node_ptr(const dof_id_type i) const =0
virtual void write(const std::string &name) libmesh_override
void clear_point_locator()
Definition: mesh_base.C:557
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:2446
void libmesh_assert_valid_amr_elem_ids(const MeshBase &mesh)
Definition: mesh_tools.C:1113
void prepare_for_use(const bool skip_renumber_nodes_and_elements=false, const bool skip_find_neighbors=false)
Definition: mesh_base.C:176
OStreamProxy err(std::cerr)
subdomain_id_type subdomain_id() const
Definition: elem.h:1952
void set_neighbor(const unsigned int i, Elem *n)
Definition: elem.h:2001
virtual void clear()
Definition: mesh_base.C:287
virtual unsigned int n_children() const =0
SimpleRange< NodeRefIter > node_ref_range()
Definition: elem.h:2048
UnstructuredMesh(const Parallel::Communicator &comm_in, unsigned char dim=1)
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:2488
std::set< GhostingFunctor * >::const_iterator ghosting_functors_begin() const
Definition: mesh_base.h:799
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual element_iterator active_pid_elements_end(processor_id_type proc_id)=0
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=0
const Point & point(const unsigned int i) const
Definition: elem.h:1810
virtual dof_id_type key(const unsigned int s) const =0
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
bool allow_renumbering() const
Definition: mesh_base.h:751
virtual unsigned int dim() const =0
unsigned int level() const
Definition: elem.h:2389
bool initialized()
Definition: libmesh.C:273
virtual Point centroid() const
Definition: elem.C:338
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Definition: elem.h:2856
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1832
void libmesh_assert_valid_neighbors(const MeshBase &mesh, bool assert_valid_remote_elems=true)
Definition: mesh_tools.C:1707
virtual void delete_remote_elements()
Definition: mesh_base.h:183
dof_id_type id() const
Definition: dof_object.h:632
virtual dof_id_type n_nodes() const =0
virtual const Elem * elem_ptr(const dof_id_type i) const =0
virtual dof_id_type n_elem() const =0
unique_id_type unique_id() const
Definition: dof_object.h:649
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=libmesh_nullptr)
Definition: elem.C:239
bool allow_remote_element_removal() const
Definition: mesh_base.h:760
OStreamProxy out(std::cout)
virtual void reserve_elem(const dof_id_type ne)=0
virtual void renumber_nodes_and_elements()=0
uint8_t dof_id_type
Definition: id_types.h:64
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:694
const RemoteElem * remote_elem
Definition: remote_elem.C:57