parallel_mesh.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2016 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 // Local includes
21 #include "libmesh/boundary_info.h"
22 #include "libmesh/elem.h"
25 #include "libmesh/parallel_mesh.h"
26 #include "libmesh/parallel.h"
28 
29 namespace libMesh
30 {
31 
32 // ------------------------------------------------------------
33 // ParallelMesh class member functions
34 ParallelMesh::ParallelMesh (const Parallel::Communicator & comm_in,
35  unsigned char d) :
36  UnstructuredMesh (comm_in,d), _is_serial(true),
37  _n_nodes(0), _n_elem(0), _max_node_id(0), _max_elem_id(0),
38  _next_free_local_node_id(this->processor_id()),
39  _next_free_local_elem_id(this->processor_id()),
40  _next_free_unpartitioned_node_id(this->n_processors()),
41  _next_free_unpartitioned_elem_id(this->n_processors())
42 #ifdef LIBMESH_ENABLE_UNIQUE_ID
43  , _next_unpartitioned_unique_id(this->n_processors())
44 #endif
45 {
46 #ifdef LIBMESH_ENABLE_UNIQUE_ID
47  _next_unique_id = this->processor_id();
48 #endif
49 
50  // FIXME: give parmetis the communicator!
52 }
53 
54 
55 #ifndef LIBMESH_DISABLE_COMMWORLD
56 // ------------------------------------------------------------
57 // ParallelMesh class member functions
58 ParallelMesh::ParallelMesh (unsigned char d) :
59  UnstructuredMesh (d), _is_serial(true),
60  _n_nodes(0), _n_elem(0), _max_node_id(0), _max_elem_id(0),
61  _next_free_local_node_id(this->processor_id()),
62  _next_free_local_elem_id(this->processor_id()),
63  _next_free_unpartitioned_node_id(this->n_processors()),
64  _next_free_unpartitioned_elem_id(this->n_processors())
65 #ifdef LIBMESH_ENABLE_UNIQUE_ID
66  , _next_unpartitioned_unique_id(this->n_processors())
67 #endif
68 {
69 #ifdef LIBMESH_ENABLE_UNIQUE_ID
70  _next_unique_id = this->processor_id();
71 #endif
72 
73  // FIXME: give parmetis the communicator!
74  _partitioner = UniquePtr<Partitioner>(new ParmetisPartitioner());
75 }
76 #endif
77 
78 
79 ParallelMesh::~ParallelMesh ()
80 {
81  this->clear(); // Free nodes and elements
82 }
83 
84 
85 // This might be specialized later, but right now it's just here to
86 // make sure the compiler doesn't give us a default (non-deep) copy
87 // constructor instead.
88 ParallelMesh::ParallelMesh (const ParallelMesh & other_mesh) :
89  UnstructuredMesh (other_mesh), _is_serial(other_mesh._is_serial),
90  _n_nodes(0), _n_elem(0), _max_node_id(0), _max_elem_id(0),
91  _next_free_local_node_id(this->processor_id()),
92  _next_free_local_elem_id(this->processor_id()),
93  _next_free_unpartitioned_node_id(this->n_processors()),
94  _next_free_unpartitioned_elem_id(this->n_processors())
95 {
96  this->copy_nodes_and_elements(other_mesh);
97  _n_nodes = other_mesh.n_nodes();
98  _n_elem = other_mesh.n_elem();
99  _max_node_id = other_mesh.max_node_id();
100  _max_elem_id = other_mesh.max_elem_id();
102  other_mesh._next_free_local_node_id;
104  other_mesh._next_free_local_elem_id;
109 #ifdef LIBMESH_ENABLE_UNIQUE_ID
111  other_mesh._next_unique_id;
114 #endif
115  this->get_boundary_info() = other_mesh.get_boundary_info();
116 
117  // Need to copy extra_ghost_elems
118  for(std::set<Elem *>::iterator it = other_mesh._extra_ghost_elems.begin();
119  it != other_mesh._extra_ghost_elems.end();
120  ++it)
121  _extra_ghost_elems.insert(elem((*it)->id()));
122 }
123 
124 
125 
127  UnstructuredMesh (other_mesh), _is_serial(other_mesh.is_serial()),
128  _n_nodes(0), _n_elem(0), _max_node_id(0), _max_elem_id(0),
129  _next_free_local_node_id(this->processor_id()),
130  _next_free_local_elem_id(this->processor_id()),
131  _next_free_unpartitioned_node_id(this->n_processors()),
132  _next_free_unpartitioned_elem_id(this->n_processors())
133 {
134  this->copy_nodes_and_elements(other_mesh);
135  this->get_boundary_info() = other_mesh.get_boundary_info();
136 
137 #ifdef LIBMESH_ENABLE_UNIQUE_ID
139 #endif
141 }
142 
143 
144 // We use cached values for these so they can be called
145 // from one processor without bothering the rest, but
146 // we may need to update those caches before doing a full
147 // renumbering
149 {
150  // This function must be run on all processors at once
151  parallel_object_only();
152 
153  _n_elem = this->parallel_n_elem();
154  _n_nodes = this->parallel_n_nodes();
157 
160  ((_max_elem_id-1) / (this->n_processors() + 1) + 1) *
161  (this->n_processors() + 1) + this->n_processors();
164  ((_max_elem_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
165  (this->n_processors() + 1) + this->processor_id();
166 
169  ((_max_node_id-1) / (this->n_processors() + 1) + 1) *
170  (this->n_processors() + 1) + this->n_processors();
173  ((_max_node_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
174  (this->n_processors() + 1) + this->processor_id();
175 
176 #ifdef LIBMESH_ENABLE_UNIQUE_ID
179  ((_next_unique_id-1) / (this->n_processors() + 1) + 1) *
180  (this->n_processors() + 1) + this->n_processors();
182  ((_next_unique_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
183  (this->n_processors() + 1) + this->processor_id();
184 #endif
185 }
186 
187 
188 // Or in debug mode we may want to test the uncached values without
189 // changing the cache
191 {
192  // This function must be run on all processors at once
193  parallel_object_only();
194 
195  dof_id_type n_local = this->n_local_elem();
196  this->comm().sum(n_local);
197  n_local += this->n_unpartitioned_elem();
198  return n_local;
199 }
200 
201 
202 
204 {
205  // This function must be run on all processors at once
206  parallel_object_only();
207 
208  dof_id_type max_local = 0;
209 
211  rit = _elements.rbegin();
212 
214  rend = _elements.rend();
215 
216  // Look for the maximum element id. Search backwards through
217  // elements so we can break out early. Beware of NULL entries that
218  // haven't yet been cleared from _elements.
219  for (; rit != rend; ++rit)
220  if (rit->second)
221  {
222  libmesh_assert_equal_to(rit->second->id(), rit->first);
223  max_local = rit->first + 1;
224  break;
225  }
226 
227  this->comm().max(max_local);
228  return max_local;
229 }
230 
231 
232 
233 #ifdef LIBMESH_ENABLE_UNIQUE_ID
235 {
236  // This function must be run on all processors at once
237  parallel_object_only();
238 
241  this->comm().max(max_local);
242  return max_local;
243 }
244 #endif
245 
246 
247 
249 {
250  // This function must be run on all processors at once
251  parallel_object_only();
252 
254  this->comm().sum(n_local);
255  n_local += this->n_unpartitioned_nodes();
256  return n_local;
257 }
258 
259 
260 
262 {
263  // This function must be run on all processors at once
264  parallel_object_only();
265 
266  dof_id_type max_local = 0;
267 
269  rit = _nodes.rbegin();
270 
272  rend = _nodes.rend();
273 
274  // Look for the maximum element id. Search backwards through
275  // elements so we can break out early. Beware of NULL entries that
276  // haven't yet been cleared from _elements.
277  for (; rit != rend; ++rit)
278  if (rit->second)
279  {
280  libmesh_assert_equal_to(rit->second->id(), rit->first);
281  max_local = rit->first + 1;
282  break;
283  }
284 
285  this->comm().max(max_local);
286  return max_local;
287 }
288 
289 
290 
291 const Point & ParallelMesh::point (const dof_id_type i) const
292 {
294  libmesh_assert_equal_to (_nodes[i]->id(), i);
295 
296  return (*_nodes[i]);
297 }
298 
299 
300 
301 
302 
303 const Node & ParallelMesh::node (const dof_id_type i) const
304 {
306  libmesh_assert_equal_to (_nodes[i]->id(), i);
307 
308  return (*_nodes[i]);
309 }
310 
311 
312 
313 
314 
316 {
318  libmesh_assert_equal_to (_nodes[i]->id(), i);
319 
320  return (*_nodes[i]);
321 }
322 
323 
324 
325 const Node * ParallelMesh::node_ptr (const dof_id_type i) const
326 {
328  libmesh_assert_equal_to (_nodes[i]->id(), i);
329 
330  return _nodes[i];
331 }
332 
333 
334 
335 
337 {
339  libmesh_assert_equal_to (_nodes[i]->id(), i);
340 
341  return _nodes[i];
342 }
343 
344 
345 
346 
348 {
349  std::map<dof_id_type, Node *>::const_iterator it = _nodes.find(i);
350  if (it != _nodes.end().it)
351  {
352  const Node * n = it->second;
353  libmesh_assert (!n || n->id() == i);
354  return n;
355  }
356 
357  return libmesh_nullptr;
358 }
359 
360 
361 
362 
364 {
365  std::map<dof_id_type, Node *>::const_iterator it = _nodes.find(i);
366  if (it != _nodes.end().it)
367  {
368  Node * n = it->second;
369  libmesh_assert (!n || n->id() == i);
370  return n;
371  }
372 
373  return libmesh_nullptr;
374 }
375 
376 
377 
378 
379 const Elem * ParallelMesh::elem (const dof_id_type i) const
380 {
382  libmesh_assert_equal_to (_elements[i]->id(), i);
383 
384  return _elements[i];
385 }
386 
387 
388 
389 
391 {
393  libmesh_assert_equal_to (_elements[i]->id(), i);
394 
395  return _elements[i];
396 }
397 
398 
399 
400 
402 {
403  std::map<dof_id_type, Elem *>::const_iterator it = _elements.find(i);
404  if (it != _elements.end().it)
405  {
406  const Elem * e = it->second;
407  libmesh_assert (!e || e->id() == i);
408  return e;
409  }
410 
411  return libmesh_nullptr;
412 }
413 
414 
415 
416 
418 {
419  std::map<dof_id_type, Elem *>::const_iterator it = _elements.find(i);
420  if (it != _elements.end().it)
421  {
422  Elem * e = _elements[i];
423  libmesh_assert (!e || e->id() == i);
424  return e;
425  }
426 
427  return libmesh_nullptr;
428 }
429 
430 
431 
432 
434 {
435  // Don't try to add NULLs!
436  libmesh_assert(e);
437 
438  // Trying to add an existing element is a no-op
439  if (e->valid_id() && _elements[e->id()] == e)
440  return e;
441 
442  const processor_id_type elem_procid = e->processor_id();
443 
444  if (!e->valid_id())
445  {
446  // We should only be creating new ids past the end of the range
447  // of existing ids
448  libmesh_assert_greater_equal(_next_free_unpartitioned_elem_id,
449  _max_elem_id);
450  libmesh_assert_greater_equal(_next_free_local_elem_id, _max_elem_id);
451 
452  // Use the unpartitioned ids for unpartitioned elems,
453  // in serial, and temporarily for ghost elems
455  if (elem_procid == this->processor_id() &&
456  !this->is_serial())
457  next_id = &_next_free_local_elem_id;
458  e->set_id (*next_id);
459  }
460 
461  {
462  // Advance next_ids up high enough that each is pointing to an
463  // unused id and any subsequent increments will still point us
464  // to unused ids
466  static_cast<dof_id_type>(e->id()+1));
467 
470  ((_max_elem_id-1) / (this->n_processors() + 1) + 1) *
471  (this->n_processors() + 1) + this->n_processors();
474  ((_max_elem_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
475  (this->n_processors() + 1) + this->processor_id();
476 
477 #ifndef NDEBUG
478  // We need a const mapvector so we don't inadvertently create
479  // NULL entries when testing for non-NULL ones
480  const mapvector<Elem *, dof_id_type> & const_elements = _elements;
481 #endif
483  libmesh_assert(!const_elements[_next_free_local_elem_id]);
484  }
485 
486  // Don't try to overwrite existing elems
487  libmesh_assert (!_elements[e->id()]);
488 
489  _elements[e->id()] = e;
490 
491  // Try to make the cached elem data more accurate
492  if (elem_procid == this->processor_id() ||
493  elem_procid == DofObject::invalid_processor_id)
494  _n_elem++;
495 
496 #ifdef LIBMESH_ENABLE_UNIQUE_ID
497  if (!e->valid_unique_id())
498  {
499  if (processor_id() == e->processor_id())
500  {
502  _next_unique_id += this->n_processors() + 1;
503  }
504  else
505  {
508  }
509  }
510 #endif
511 
512  // Unpartitioned elems should be added on every processor
513  // And shouldn't be added in the same batch as ghost elems
514  // But we might be just adding on processor 0 to
515  // broadcast later
516  // #ifdef DEBUG
517  // if (elem_procid == DofObject::invalid_processor_id)
518  // {
519  // dof_id_type elem_id = e->id();
520  // this->comm().max(elem_id);
521  // libmesh_assert_equal_to (elem_id, e->id());
522  // }
523  // #endif
524 
525  return e;
526 }
527 
528 
529 
531 {
532  if (_elements[e->id()])
533  this->delete_elem(_elements[e->id()]);
534 
535 #ifdef LIBMESH_ENABLE_UNIQUE_ID
536  if (!e->valid_unique_id())
537  {
538  if (processor_id() == e->processor_id())
539  {
541  _next_unique_id += this->n_processors() + 1;
542  }
543  else
544  {
547  }
548  }
549 #endif
550 
551  // Try to make the cached elem data more accurate
552  processor_id_type elem_procid = e->processor_id();
553  if (elem_procid == this->processor_id() ||
554  elem_procid == DofObject::invalid_processor_id)
555  _n_elem++;
556 
557  _elements[e->id()] = e;
558 
559  return e;
560 }
561 
562 
563 
565 {
566  libmesh_assert (e);
567 
568  // Try to make the cached elem data more accurate
569  processor_id_type elem_procid = e->processor_id();
570  if (elem_procid == this->processor_id() ||
571  elem_procid == DofObject::invalid_processor_id)
572  _n_elem--;
573 
574  // Delete the element from the BoundaryInfo object
575  this->get_boundary_info().remove(e);
576 
577  // But not yet from the container; we might invalidate
578  // an iterator that way!
579 
580  //_elements.erase(e->id());
581 
582  // Instead, we set it to NULL for now
583 
584  _elements[e->id()] = libmesh_nullptr;
585 
586  // delete the element
587  delete e;
588 }
589 
590 
591 
593  const dof_id_type new_id)
594 {
595  Elem * el = _elements[old_id];
596  libmesh_assert (el);
597  libmesh_assert_equal_to (el->id(), old_id);
598 
599  el->set_id(new_id);
600  libmesh_assert (!_elements[new_id]);
601  _elements[new_id] = el;
602  _elements.erase(old_id);
603 }
604 
605 
606 
608  const dof_id_type id,
609  const processor_id_type proc_id)
610 {
611  if (_nodes.count(id))
612  {
613  Node * n = _nodes[id];
614  libmesh_assert (n);
615  libmesh_assert_equal_to (n->id(), id);
616 
617  *n = p;
618  n->processor_id() = proc_id;
619 
620  return n;
621  }
622 
623  Node * n = Node::build(p, id).release();
624  n->processor_id() = proc_id;
625 
626  return ParallelMesh::add_node(n);
627 }
628 
629 
630 
632 {
633  // Don't try to add NULLs!
634  libmesh_assert(n);
635 
636  // Trying to add an existing node is a no-op
637  if (n->valid_id() && _nodes[n->id()] == n)
638  return n;
639 
640  const processor_id_type node_procid = n->processor_id();
641 
642  if (!n->valid_id())
643  {
644  // We should only be creating new ids past the end of the range
645  // of existing ids
646  libmesh_assert_greater_equal(_next_free_unpartitioned_node_id,
647  _max_node_id);
648  libmesh_assert_greater_equal(_next_free_local_node_id, _max_node_id);
649 
650  // Use the unpartitioned ids for unpartitioned nodes,
651  // in serial, and temporarily for ghost nodes
653  if (node_procid == this->processor_id() &&
654  !this->is_serial())
655  next_id = &_next_free_local_node_id;
656  n->set_id (*next_id);
657  }
658 
659  {
660  // Advance next_ids up high enough that each is pointing to an
661  // unused id and any subsequent increments will still point us
662  // to unused ids
664  static_cast<dof_id_type>(n->id()+1));
665 
668  ((_max_node_id-1) / (this->n_processors() + 1) + 1) *
669  (this->n_processors() + 1) + this->n_processors();
672  ((_max_node_id + this->n_processors() - 1) / (this->n_processors() + 1) + 1) *
673  (this->n_processors() + 1) + this->processor_id();
674 
675 #ifndef NDEBUG
676  // We need a const mapvector so we don't inadvertently create
677  // NULL entries when testing for non-NULL ones
678  const mapvector<Node *,dof_id_type> & const_nodes = _nodes;
679 #endif
682  }
683 
684  // Don't try to overwrite existing nodes
685  libmesh_assert (!_nodes[n->id()]);
686 
687  _nodes[n->id()] = n;
688 
689  // Try to make the cached node data more accurate
690  if (node_procid == this->processor_id() ||
691  node_procid == DofObject::invalid_processor_id)
692  _n_nodes++;
693 
694 #ifdef LIBMESH_ENABLE_UNIQUE_ID
695  if (!n->valid_unique_id())
696  {
697  if (processor_id() == n->processor_id())
698  {
700  _next_unique_id += this->n_processors();
701  }
702  else
703  {
706  }
707  }
708 #endif
709 
710 
711  // Unpartitioned nodes should be added on every processor
712  // And shouldn't be added in the same batch as ghost nodes
713  // But we might be just adding on processor 0 to
714  // broadcast later
715  // #ifdef DEBUG
716  // if (node_procid == DofObject::invalid_processor_id)
717  // {
718  // dof_id_type node_id = n->id();
719  // this->comm().max(node_id);
720  // libmesh_assert_equal_to (node_id, n->id());
721  // }
722  // #endif
723 
724  return n;
725 }
726 
727 
728 
730 {
731  return ParallelMesh::add_node(n);
732 }
733 
734 
735 
737 {
738  libmesh_assert(n);
739  libmesh_assert(_nodes[n->id()]);
740 
741  // Try to make the cached elem data more accurate
742  processor_id_type node_procid = n->processor_id();
743  if (node_procid == this->processor_id() ||
744  node_procid == DofObject::invalid_processor_id)
745  _n_nodes--;
746 
747  // Delete the node from the BoundaryInfo object
748  this->get_boundary_info().remove(n);
749 
750  // But not yet from the container; we might invalidate
751  // an iterator that way!
752 
753  //_nodes.erase(n->id());
754 
755  // Instead, we set it to NULL for now
756 
757  _nodes[n->id()] = libmesh_nullptr;
758 
759  // delete the node
760  delete n;
761 }
762 
763 
764 
766  const dof_id_type new_id)
767 {
768  Node * nd = _nodes[old_id];
769  libmesh_assert (nd);
770  libmesh_assert_equal_to (nd->id(), old_id);
771 
772  nd->set_id(new_id);
773 
774  // If we have nodes shipped to this processor for NodeConstraints
775  // use, then those nodes will exist in _nodes, but may not be
776  // locatable via a TopologyMap due to the insufficiency of elements
777  // connecting to them. If local refinement then wants to create a
778  // *new* node in the same location, it will initally get a temporary
779  // id, and then make_node_ids_parallel_consistent() will try to move
780  // it to the canonical id. We need to account for this case to
781  // avoid false positives and memory leaks.
782 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
783  if (_nodes[new_id])
784  {
785  libmesh_assert_equal_to (*(Point *)_nodes[new_id],
786  *(Point *)_nodes[old_id]);
787  _nodes.erase(new_id);
788  }
789 #else
790  // If we aren't shipping nodes for NodeConstraints, there should be
791  // no reason for renumbering one node onto another.
792  libmesh_assert (!_nodes[new_id]);
793 #endif
794  _nodes[new_id] = nd;
795  _nodes.erase(old_id);
796 }
797 
798 
799 
801 {
802  // Call parent clear function
803  MeshBase::clear();
804 
805 
806  // Clear our elements and nodes
807  {
808  elem_iterator_imp it = _elements.begin();
809  const elem_iterator_imp end = _elements.end();
810 
811  // There is no need to remove the elements from
812  // the BoundaryInfo data structure since we
813  // already cleared it.
814  for (; it != end; ++it)
815  delete *it;
816 
817  _elements.clear();
818  }
819 
820  // clear the nodes data structure
821  {
822  node_iterator_imp it = _nodes.begin();
823  node_iterator_imp end = _nodes.end();
824 
825  // There is no need to remove the nodes from
826  // the BoundaryInfo data structure since we
827  // already cleared it.
828  for (; it != end; ++it)
829  delete *it;
830 
831  _nodes.clear();
832  }
833 
834  // We're no longer distributed if we were before
835  _is_serial = true;
836 
837  // Correct our caches
838  _n_nodes = 0;
839  _n_elem = 0;
840  _max_node_id = 0;
841  _max_elem_id = 0;
846 }
847 
848 
849 
851 {
852  // If this is a truly parallel mesh, go through the redistribution/gather/delete remote steps
853  if (!this->is_serial())
854  {
855  // Construct a MeshCommunication object to actually redistribute the nodes
856  // and elements according to the partitioner, and then to re-gather the neighbors.
858  mc.redistribute(*this);
859 
861 
862  // We probably had valid neighbors previously, so that a quality
863  // new partitioning could be found, but we might not have valid
864  // neighbor links on the newly-redistributed elements
865  this->find_neighbors();
866 
867  // Is this necessary? If we are called from prepare_for_use(), this will be called
868  // anyway... but users can always call partition directly, in which case we do need
869  // to call delete_remote_elements()...
870  //
871  // Regardless of whether it's necessary, it isn't safe. We
872  // haven't communicated new node processor_ids yet, and we can't
873  // delete nodes until we do.
874  // this->delete_remote_elements();
875  }
876 }
877 
878 
879 
881 {
882  // this->recalculate_n_partitions();
883 
884  // Partitioning changes our numbers of unpartitioned objects
886 }
887 
888 
889 
890 template <typename T>
892 {
893  // This function must be run on all processors at once
894  parallel_object_only();
895 
896  const dof_id_type pmax_node_id = this->parallel_max_node_id();
897  const dof_id_type pmax_elem_id = this->parallel_max_elem_id();
898  const dof_id_type pmax_id = std::max(pmax_node_id, pmax_elem_id);
899 
900  for (dof_id_type i=0; i != pmax_id; ++i)
901  {
902  T * obj = objects[i]; // Returns NULL if there's no map entry
903 
904  // Local lookups by id should return the requested object
905  libmesh_assert(!obj || obj->id() == i);
906 
907  // All processors with an object should agree on id
908  const dof_id_type dofid = obj && obj->valid_id() ?
909  obj->id() : DofObject::invalid_id;
910  libmesh_assert(this->comm().semiverify(obj ? &dofid : libmesh_nullptr));
911 
912  // All processors with an object should agree on processor id
913  const dof_id_type procid = obj && obj->valid_processor_id() ?
914  obj->processor_id() : DofObject::invalid_processor_id;
915  libmesh_assert(this->comm().semiverify(obj ? &procid : libmesh_nullptr));
916 
917  dof_id_type min_procid = procid;
918  this->comm().min(min_procid);
919 
920  // Either:
921  // 1.) I own this elem (min_procid == this->processor_id()) *and* I have a valid pointer to it (obj != NULL)
922  // or
923  // 2.) I don't own this elem (min_procid != this->processor_id()). (In this case I may or may not have a valid pointer to it.)
924 
925  // Original assert logic
926  // libmesh_assert (min_procid != this->processor_id() || obj);
927 
928  // More human-understandable logic...
930  ((min_procid == this->processor_id()) && obj)
931  ||
932  (min_procid != this->processor_id())
933  );
934 
935 #ifdef LIBMESH_ENABLE_UNIQUE_ID
936  // All processors with an object should agree on unique id
937  const unique_id_type uniqueid = obj ? obj->unique_id() : 0;
938  libmesh_assert(this->comm().semiverify(obj ? &uniqueid : libmesh_nullptr));
939 #endif
940  }
941 }
942 
943 
944 
946 {
949 }
950 
951 
952 
954 {
955  // This function must be run on all processors at once
956  parallel_object_only();
957 
958  dof_id_type pmax_elem_id = this->parallel_max_elem_id();
959 
960  for (dof_id_type i=0; i != pmax_elem_id; ++i)
961  {
962  Elem * el = _elements[i]; // Returns NULL if there's no map entry
963 
964  unsigned int p_level = el ? (el->p_level()) : libMesh::invalid_uint;
965 
966  // All processors with an active element should agree on p level
967  libmesh_assert(this->comm().semiverify((el && el->active()) ? &p_level : libmesh_nullptr));
968  }
969 }
970 
971 
972 
973 
975 {
976 #ifdef LIBMESH_ENABLE_AMR
977  // This function must be run on all processors at once
978  parallel_object_only();
979 
980  dof_id_type pmax_elem_id = this->parallel_max_elem_id();
981 
982  for (dof_id_type i=0; i != pmax_elem_id; ++i)
983  {
984  Elem * el = _elements[i]; // Returns NULL if there's no map entry
985 
986  unsigned int refinement_flag = el ?
987  static_cast<unsigned int> (el->refinement_flag()) : libMesh::invalid_uint;
988  unsigned int p_refinement_flag = el ?
989  static_cast<unsigned int> (el->p_refinement_flag()) : libMesh::invalid_uint;
990 
991  libmesh_assert(this->comm().semiverify(el ? &refinement_flag : libmesh_nullptr));
992 
993  // p refinement flags aren't always kept correct on inactive
994  // ghost elements
995  libmesh_assert(this->comm().semiverify((el && el->active()) ? &p_refinement_flag : libmesh_nullptr));
996  }
997 #endif // LIBMESH_ENABLE_AMR
998 }
999 
1000 
1001 
1002 template <typename T>
1005 {
1006  // This function must be run on all processors at once
1007  parallel_object_only();
1008 
1009  typedef typename mapvector<T *,dof_id_type>::veclike_iterator object_iterator;
1010 
1011  // In parallel we may not know what objects other processors have.
1012  // Start by figuring out how many
1013  dof_id_type unpartitioned_objects = 0;
1014 
1015  std::vector<dof_id_type>
1016  ghost_objects_from_proc(this->n_processors(), 0);
1017 
1018  object_iterator it = objects.begin();
1019  object_iterator end = objects.end();
1020 
1021  for (; it != end;)
1022  {
1023  T * obj = *it;
1024 
1025  // Remove any NULL container entries while we're here,
1026  // being careful not to invalidate our iterator
1027  if (!*it)
1028  objects.erase(it++);
1029  else
1030  {
1031  processor_id_type obj_procid = obj->processor_id();
1032  if (obj_procid == DofObject::invalid_processor_id)
1033  unpartitioned_objects++;
1034  else
1035  ghost_objects_from_proc[obj_procid]++;
1036  ++it;
1037  }
1038  }
1039 
1040  std::vector<dof_id_type> objects_on_proc(this->n_processors(), 0);
1041  this->comm().allgather(ghost_objects_from_proc[this->processor_id()],
1042  objects_on_proc);
1043 
1044 #ifndef NDEBUG
1045  libmesh_assert(this->comm().verify(unpartitioned_objects));
1046  for (processor_id_type p=0; p != this->n_processors(); ++p)
1047  libmesh_assert_less_equal (ghost_objects_from_proc[p], objects_on_proc[p]);
1048 #endif
1049 
1050  // We'll renumber objects in blocks by processor id
1051  std::vector<dof_id_type> first_object_on_proc(this->n_processors());
1052  for (processor_id_type i=1; i != this->n_processors(); ++i)
1053  first_object_on_proc[i] = first_object_on_proc[i-1] +
1054  objects_on_proc[i-1];
1055  dof_id_type next_id = first_object_on_proc[this->processor_id()];
1056  dof_id_type first_free_id =
1057  first_object_on_proc[this->n_processors()-1] +
1058  objects_on_proc[this->n_processors()-1] +
1059  unpartitioned_objects;
1060 
1061  // First set new local object ids and build request sets
1062  // for non-local object ids
1063 
1064  // Request sets to send to each processor
1065  std::vector<std::vector<dof_id_type> >
1066  requested_ids(this->n_processors());
1067 
1068 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1069  std::vector<std::vector<unique_id_type> >
1070  requested_unique_ids(this->n_processors());
1071 #endif
1072 
1073  // We know how many objects live on each processor, so reseve() space for
1074  // each.
1075  for (processor_id_type p=0; p != this->n_processors(); ++p)
1076  if (p != this->processor_id())
1077  {
1078  requested_ids[p].reserve(ghost_objects_from_proc[p]);
1079 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1080  requested_unique_ids[p].reserve(ghost_objects_from_proc[p]);
1081 #endif
1082  }
1083 
1084  end = objects.end();
1085  for (it = objects.begin(); it != end; ++it)
1086  {
1087  T * obj = *it;
1088  if (obj->processor_id() == this->processor_id())
1089  obj->set_id(next_id++);
1090  else if (obj->processor_id() != DofObject::invalid_processor_id)
1091  {
1092  requested_ids[obj->processor_id()].push_back(obj->id());
1093 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1094  // It's possible to have an invalid id for dofs not owned by this process.
1095  // We'll assert that they match on the receiving end.
1096  requested_unique_ids[obj->processor_id()].push_back(obj->valid_unique_id() ? obj-> unique_id() : DofObject::invalid_unique_id);
1097 #endif
1098  }
1099  }
1100 
1101  // Next set ghost object ids from other processors
1102  if (this->n_processors() > 1)
1103  {
1104  for (processor_id_type p=1; p != this->n_processors(); ++p)
1105  {
1106  // Trade my requests with processor procup and procdown
1107  processor_id_type procup = cast_int<processor_id_type>
1108  ((this->processor_id() + p) % this->n_processors());
1109  processor_id_type procdown = cast_int<processor_id_type>
1110  ((this->n_processors() + this->processor_id() - p) %
1111  this->n_processors());
1112  std::vector<dof_id_type> request_to_fill;
1113  this->comm().send_receive(procup, requested_ids[procup],
1114  procdown, request_to_fill);
1115 
1116 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1117  std::vector<unique_id_type> unique_request_to_fill;
1118  this->comm().send_receive(procup, requested_unique_ids[procup],
1119  procdown, unique_request_to_fill);
1120  std::vector<unique_id_type> new_unique_ids(unique_request_to_fill.size());
1121 #endif
1122 
1123  // Fill those requests
1124  std::vector<dof_id_type> new_ids(request_to_fill.size());
1125  for (std::size_t i=0; i != request_to_fill.size(); ++i)
1126  {
1127  T * obj = objects[request_to_fill[i]];
1128  libmesh_assert(obj);
1129  libmesh_assert_equal_to (obj->processor_id(), this->processor_id());
1130  new_ids[i] = obj->id();
1131 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1132  new_unique_ids[i] = obj->valid_unique_id() ? obj->unique_id() : DofObject::invalid_unique_id;
1133 #endif
1134 
1135  libmesh_assert_greater_equal (new_ids[i],
1136  first_object_on_proc[this->processor_id()]);
1137  libmesh_assert_less (new_ids[i],
1138  first_object_on_proc[this->processor_id()] +
1139  objects_on_proc[this->processor_id()]);
1140  }
1141 
1142  // Trade back the results
1143  std::vector<dof_id_type> filled_request;
1144  this->comm().send_receive(procdown, new_ids,
1145  procup, filled_request);
1146 
1147 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1148  std::vector<unique_id_type> unique_filled_request;
1149  this->comm().send_receive(procdown, new_unique_ids,
1150  procup, unique_filled_request);
1151 #endif
1152 
1153  // And copy the id changes we've now been informed of
1154  for (std::size_t i=0; i != filled_request.size(); ++i)
1155  {
1156  T * obj = objects[requested_ids[procup][i]];
1157  libmesh_assert (obj);
1158  libmesh_assert_equal_to (obj->processor_id(), procup);
1159  libmesh_assert_greater_equal (filled_request[i],
1160  first_object_on_proc[procup]);
1161  libmesh_assert_less (filled_request[i],
1162  first_object_on_proc[procup] +
1163  objects_on_proc[procup]);
1164  obj->set_id(filled_request[i]);
1165 
1166 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1167  if (!obj->valid_unique_id() && unique_filled_request[i] != DofObject::invalid_unique_id)
1168  obj->set_unique_id() = unique_filled_request[i];
1169 #endif
1170  }
1171  }
1172  }
1173 
1174  // Next set unpartitioned object ids
1175  next_id = 0;
1176  for (processor_id_type i=0; i != this->n_processors(); ++i)
1177  next_id += objects_on_proc[i];
1178  for (it = objects.begin(); it != end; ++it)
1179  {
1180  T * obj = *it;
1181  if (obj->processor_id() == DofObject::invalid_processor_id)
1182  obj->set_id(next_id++);
1183  }
1184 
1185  // Finally shuffle around objects so that container indices
1186  // match ids
1187  end = objects.end();
1188  for (it = objects.begin(); it != end;)
1189  {
1190  T * obj = *it;
1191  if (obj) // don't try shuffling already-NULL entries
1192  {
1193  T * next = objects[obj->id()];
1194  // If we have to move this object
1195  if (next != obj)
1196  {
1197  // NULL out its original position for now
1198  // (our shuffling may put another object there shortly)
1199  *it = libmesh_nullptr;
1200 
1201  // There may already be another object with this id that
1202  // needs to be moved itself
1203  while (next)
1204  {
1205  // We shouldn't be trying to give two objects the
1206  // same id
1207  libmesh_assert_not_equal_to (next->id(), obj->id());
1208  objects[obj->id()] = obj;
1209  obj = next;
1210  next = objects[obj->id()];
1211  }
1212  objects[obj->id()] = obj;
1213  }
1214  }
1215  // Remove any container entries that were left as NULL,
1216  // being careful not to invalidate our iterator
1217  if (!*it)
1218  objects.erase(it++);
1219  else
1220  ++it;
1221  }
1222 
1223  return first_free_id;
1224 }
1225 
1226 
1228 {
1229  parallel_object_only();
1230 
1231 #ifdef DEBUG
1232  // Make sure our ids and flags are consistent
1236 #endif
1237 
1238  START_LOG("renumber_nodes_and_elements()", "ParallelMesh");
1239 
1240  std::set<dof_id_type> used_nodes;
1241 
1242  // flag the nodes we need
1243  {
1246 
1247  for (; it != end; ++it)
1248  {
1249  Elem * el = *it;
1250 
1251  for (unsigned int n=0; n != el->n_nodes(); ++n)
1252  used_nodes.insert(el->node(n));
1253  }
1254  }
1255 
1256  // Nodes not connected to any local elements, and NULL node entries
1257  // in our container, are deleted
1258  {
1259  node_iterator_imp it = _nodes.begin();
1260  node_iterator_imp end = _nodes.end();
1261 
1262  for (; it != end;)
1263  {
1264  Node * nd = *it;
1265  if (!nd)
1266  _nodes.erase(it++);
1267  else if (!used_nodes.count(nd->id()))
1268  {
1269  // remove any boundary information associated with
1270  // this node
1271  this->get_boundary_info().remove (nd);
1272 
1273  // delete the node
1274  delete nd;
1275 
1276  _nodes.erase(it++);
1277  }
1278  else
1279  ++it;
1280  }
1281  }
1282 
1284  {
1285  this->update_parallel_id_counts();
1286  STOP_LOG("renumber_nodes_and_elements()", "ParallelMesh");
1287  return;
1288  }
1289 
1290  // Finally renumber all the elements
1291  _n_elem = this->renumber_dof_objects (this->_elements);
1292 
1293  // and all the remaining nodes
1294  _n_nodes = this->renumber_dof_objects (this->_nodes);
1295 
1296  // And figure out what IDs we should use when adding new nodes and
1297  // new elements
1298  this->update_parallel_id_counts();
1299 
1300  // Make sure our caches are up to date and our
1301  // DofObjects are well packed
1302 #ifdef DEBUG
1303  libmesh_assert_equal_to (this->n_nodes(), this->parallel_n_nodes());
1304  libmesh_assert_equal_to (this->n_elem(), this->parallel_n_elem());
1305  const dof_id_type pmax_node_id = this->parallel_max_node_id();
1306  const dof_id_type pmax_elem_id = this->parallel_max_elem_id();
1307  libmesh_assert_equal_to (this->max_node_id(), pmax_node_id);
1308  libmesh_assert_equal_to (this->max_elem_id(), pmax_elem_id);
1309  libmesh_assert_equal_to (this->n_nodes(), this->max_node_id());
1310  libmesh_assert_equal_to (this->n_elem(), this->max_elem_id());
1311 
1312  // Make sure our ids and flags are consistent
1315 
1316  // And make sure we've made our numbering monotonic
1318 #endif
1319 
1320  STOP_LOG("renumber_nodes_and_elements()", "ParallelMesh");
1321 }
1322 
1323 
1324 
1326 {
1327  // We need access to iterators for the underlying containers,
1328  // not the mapvector<> reimplementations.
1331 
1332  // Nodes first
1333  {
1335  it = nodes.begin(),
1336  end = nodes.end();
1337 
1338  for (; it != end; ++it)
1339  if (it->second != libmesh_nullptr)
1340  it->second->set_id() = it->first;
1341  }
1342 
1343  // Elements next
1344  {
1346  it = elems.begin(),
1347  end = elems.end();
1348 
1349  for (; it != end; ++it)
1350  if (it->second != libmesh_nullptr)
1351  it->second->set_id() = it->first;
1352  }
1353 }
1354 
1355 
1356 
1358 {
1359  parallel_object_only();
1360 
1361  // Get local active elements first
1362  dof_id_type active_elements =
1363  static_cast<dof_id_type>(std::distance (this->active_local_elements_begin(),
1364  this->active_local_elements_end()));
1365  this->comm().sum(active_elements);
1366 
1367  // Then add unpartitioned active elements, which should exist on
1368  // every processor
1369  active_elements +=
1370  static_cast<dof_id_type>(std::distance
1373  return active_elements;
1374 }
1375 
1376 
1377 
1379 {
1380 #ifdef DEBUG
1381  // Make sure our neighbor links are all fine
1383 
1384  // And our child/parent links, and our flags
1386 
1387  // Make sure our ids and flags are consistent
1390 
1391  libmesh_assert_equal_to (this->n_nodes(), this->parallel_n_nodes());
1392  libmesh_assert_equal_to (this->n_elem(), this->parallel_n_elem());
1393  const dof_id_type pmax_node_id = this->parallel_max_node_id();
1394  const dof_id_type pmax_elem_id = this->parallel_max_elem_id();
1395  libmesh_assert_equal_to (this->max_node_id(), pmax_node_id);
1396  libmesh_assert_equal_to (this->max_elem_id(), pmax_elem_id);
1397 #endif
1398 
1399  _is_serial = false;
1401 
1402  libmesh_assert_equal_to (this->max_elem_id(), this->parallel_max_elem_id());
1403 
1404  // Now make sure the containers actually shrink - strip
1405  // any newly-created NULL voids out of the element array
1408  for (; e_it != e_end;)
1409  if (!*e_it)
1410  _elements.erase(e_it++);
1411  else
1412  ++e_it;
1413 
1416  for (; n_it != n_end;)
1417  if (!*n_it)
1418  _nodes.erase(n_it++);
1419  else
1420  ++n_it;
1421 
1422  // We may have deleted no-longer-connected nodes or coarsened-away
1423  // elements; let's update our caches.
1424  this->update_parallel_id_counts();
1425 
1426 #ifdef DEBUG
1427  // We might not have well-packed objects if the user didn't allow us
1428  // to renumber
1429  // libmesh_assert_equal_to (this->n_nodes(), this->max_node_id());
1430  // libmesh_assert_equal_to (this->n_elem(), this->max_elem_id());
1431 
1432  // Make sure our neighbor links are all fine
1434 
1435  // And our child/parent links, and our flags
1437 
1438  // Make sure our ids and flags are consistent
1441 #endif
1442 }
1443 
1444 
1446 {
1447  // First add the elem like normal
1448  add_elem(e);
1449 
1450  // Now add it to the set that won't be deleted when we call
1451  // delete_remote_elements()
1452  _extra_ghost_elems.insert(e);
1453 }
1454 
1455 
1457 {
1458  if (_is_serial)
1459  return;
1460  _is_serial = true;
1461  MeshCommunication().allgather(*this);
1462 
1463  // Make sure our caches are up to date and our
1464  // DofObjects are well packed
1465 #ifdef DEBUG
1466  libmesh_assert_equal_to (this->n_nodes(), this->parallel_n_nodes());
1467  libmesh_assert_equal_to (this->n_elem(), this->parallel_n_elem());
1468  const dof_id_type pmax_node_id = this->parallel_max_node_id();
1469  const dof_id_type pmax_elem_id = this->parallel_max_elem_id();
1470  libmesh_assert_equal_to (this->max_node_id(), pmax_node_id);
1471  libmesh_assert_equal_to (this->max_elem_id(), pmax_elem_id);
1472 
1473  // If we've disabled renumbering we can't be sure we're contiguous
1474  // libmesh_assert_equal_to (this->n_nodes(), this->max_node_id());
1475  // libmesh_assert_equal_to (this->n_elem(), this->max_elem_id());
1476 
1477  // Make sure our neighbor links are all fine
1479 
1480  // Make sure our ids and flags are consistent
1483 #endif
1484 }
1485 
1486 
1487 } // namespace libMesh
virtual const Point & point(const dof_id_type i) const libmesh_override
virtual void update_post_partitioning() libmesh_override
std::map< index_t, Val > maptype
Definition: mapvector.h:41
std::set< Elem * > _extra_ghost_elems
const BoundaryInfo & get_boundary_info() const
Definition: mesh_base.h:111
unique_id_type & set_unique_id()
Definition: dof_object.h:649
virtual const Node * node_ptr(const dof_id_type i) const libmesh_override
bool _skip_renumber_nodes_and_elements
Definition: mesh_base.h:1070
bool valid_id() const
Definition: dof_object.h:661
mapvector< Node *, dof_id_type > _nodes
virtual unique_id_type parallel_max_unique_id() const =0
bool active() const
Definition: elem.h:1721
dof_id_type parallel_max_node_id() const
const unsigned int invalid_uint
Definition: libmesh.h:172
virtual void allgather() libmesh_override
libmesh_assert(remote_elem)
virtual void copy_nodes_and_elements(const UnstructuredMesh &other_mesh, const bool skip_find_neighbors=false)
STOP_LOG("std::sqrt()","ExactErrorEstimator")
unsigned int p_level() const
Definition: elem.h:1886
dof_id_type n_local_nodes() const
Definition: mesh_base.h:232
dof_id_type _next_free_unpartitioned_elem_id
virtual void renumber_nodes_and_elements() libmesh_override
virtual const Node & node(const dof_id_type i) const libmesh_override
void libmesh_assert_valid_refinement_tree(const MeshBase &mesh)
Definition: mesh_tools.C:1541
void remove(const Node *node)
dof_id_type n_unpartitioned_elem() const
Definition: mesh_base.h:332
mapvector< Elem *, dof_id_type > _elements
processor_id_type n_processors() const
uint8_t processor_id_type
Definition: id_types.h:99
virtual element_iterator active_local_elements_end() libmesh_override
const class libmesh_nullptr_t libmesh_nullptr
static UniquePtr< Node > build(const Node &n)
Definition: node.h:285
void libmesh_assert_valid_parallel_object_ids(const mapvector< T *, dof_id_type > &) const
ParallelMesh(const Parallel::Communicator &comm_in, unsigned char dim=1)
virtual void update_parallel_id_counts() libmesh_override
virtual Node * add_node(Node *n) libmesh_override
virtual bool is_serial() const libmesh_override
IterBase * end
virtual void libmesh_assert_valid_parallel_ids() const libmesh_override
dof_id_type parallel_max_elem_id() const
virtual dof_id_type max_elem_id() const libmesh_override
void redistribute(ParallelMesh &) const
virtual void fix_broken_node_and_element_numbering() libmesh_override
virtual void renumber_node(dof_id_type old_id, dof_id_type new_id) libmesh_override
long double max(long double a, double b)
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true) libmesh_override
virtual const Node * query_node_ptr(const dof_id_type i) const libmesh_override
virtual void clear() libmesh_override
dof_id_type & set_id()
Definition: dof_object.h:628
bool valid_unique_id() const
Definition: dof_object.h:669
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
virtual const Elem * query_elem(const dof_id_type i) const libmesh_override
dof_id_type _next_free_local_elem_id
unique_id_type _next_unique_id
Definition: mesh_base.h:1057
virtual element_iterator active_pid_elements_begin(processor_id_type proc_id) libmesh_override
virtual Elem * add_elem(Elem *e) libmesh_override
dof_id_type renumber_dof_objects(mapvector< T *, dof_id_type > &)
virtual dof_id_type n_nodes() const libmesh_override
virtual void delete_elem(Elem *e) libmesh_override
virtual dof_id_type n_elem() const libmesh_override
virtual unsigned int n_nodes() const =0
static const unique_id_type invalid_unique_id
Definition: dof_object.h:340
static const processor_id_type invalid_processor_id
Definition: dof_object.h:346
void libmesh_assert_valid_parallel_p_levels() const
void delete_remote_elements(ParallelMesh &, const std::set< Elem * > &) const
virtual void delete_node(Node *n) libmesh_override
void erase(index_t i)
Definition: mapvector.h:116
virtual void delete_remote_elements() libmesh_override
static const dof_id_type invalid_id
Definition: dof_object.h:335
dof_id_type n_unpartitioned_nodes() const
Definition: mesh_base.h:238
RefinementState p_refinement_flag() const
Definition: elem.h:1954
void libmesh_assert_valid_parallel_flags() const
virtual Node * insert_node(Node *n) libmesh_override
veclike_iterator end()
Definition: mapvector.h:132
dof_id_type node(const unsigned int i) const
Definition: elem.h:1499
virtual void clear()
Definition: mesh_base.C:238
dof_id_type _next_free_local_node_id
dof_id_type _max_node_id
virtual element_iterator elements_begin() libmesh_override
virtual void renumber_elem(dof_id_type old_id, dof_id_type new_id) libmesh_override
void allgather(ParallelMesh &mesh) const
virtual void redistribute() libmesh_override
virtual Elem * insert_elem(Elem *e) libmesh_override
virtual element_iterator active_local_elements_begin() libmesh_override
static const unsigned int next[3]
dof_id_type n_local_elem() const
Definition: mesh_base.h:326
void allgather(T send, std::vector< T > &recv) const
bool verify(const T &r, const Communicator &comm=Communicator_World)
veclike_iterator begin()
Definition: mapvector.h:124
virtual dof_id_type parallel_n_nodes() const libmesh_override
const Parallel::Communicator & comm() const
dof_id_type _next_free_unpartitioned_node_id
virtual void add_extra_ghost_elem(Elem *e)
virtual dof_id_type parallel_n_elem() const libmesh_override
virtual unique_id_type parallel_max_unique_id() const libmesh_override
virtual dof_id_type n_active_elem() const libmesh_override
RefinementState refinement_flag() const
Definition: elem.h:1938
void send_receive(const unsigned int dest_processor_id, T1 &send, const unsigned int source_processor_id, T2 &recv, const MessageTag &send_tag=no_tag, const MessageTag &recv_tag=any_tag) const
virtual const Elem * elem(const dof_id_type i) const libmesh_override
virtual dof_id_type max_node_id() const libmesh_override
virtual element_iterator elements_end() libmesh_override
void libmesh_assert_valid_neighbors(const MeshBase &mesh, bool assert_valid_remote_elems=true)
Definition: mesh_tools.C:1581
dof_id_type id() const
Definition: dof_object.h:619
dof_id_type _max_elem_id
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) libmesh_override
processor_id_type processor_id()
Definition: libmesh_base.h:96
virtual element_iterator active_pid_elements_end(processor_id_type proc_id) libmesh_override
uint8_t unique_id_type
Definition: id_types.h:79
ParallelMesh::ParallelMesh(const Parallel::Communicator &comm_in, unsigned char d) _partitioner
Definition: parallel_mesh.C:51
PetscInt n_local
unique_id_type _next_unpartitioned_unique_id
uint8_t dof_id_type
Definition: id_types.h:64
processor_id_type processor_id() const
void libmesh_assert_valid_elem_ids(const MeshBase &mesh)
Definition: mesh_tools.C:1164
processor_id_type processor_id() const
Definition: dof_object.h:681
START_LOG("std::sqrt()","ExactErrorEstimator")
processor_id_type n_processors()
Definition: libmesh_base.h:88