libMesh
unstructured_mesh.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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"
32 #include "libmesh/ghosting_functor.h"
33 #include "libmesh/unstructured_mesh.h"
34 #include "libmesh/libmesh_logging.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 #include "libmesh/namebased_io.h"
40 #include "libmesh/partitioner.h"
41 #include "libmesh/enum_order.h"
42 #include "libmesh/mesh_communication.h"
43 
44 
45 
46 namespace libMesh
47 {
48 
49 
50 // ------------------------------------------------------------
51 // UnstructuredMesh class member functions
52 UnstructuredMesh::UnstructuredMesh (const Parallel::Communicator & comm_in,
53  unsigned char d) :
54  MeshBase (comm_in,d)
55 {
57 }
58 
59 
60 
62  const bool skip_find_neighbors,
63  dof_id_type element_id_offset,
64  dof_id_type node_id_offset,
66 #ifdef LIBMESH_ENABLE_UNIQUE_ID
67  unique_id_offset
68 #endif
69  )
70 {
71  LOG_SCOPE("copy_nodes_and_elements()", "UnstructuredMesh");
72 
73  std::pair<std::vector<unsigned int>, std::vector<unsigned int>>
74  extra_int_maps = this->merge_extra_integer_names(other_mesh);
75 
76  const unsigned int n_old_node_ints = extra_int_maps.second.size(),
77  n_new_node_ints = _node_integer_names.size(),
78  n_old_elem_ints = extra_int_maps.first.size(),
79  n_new_elem_ints = _elem_integer_names.size();
80 
81  // If we are partitioned into fewer parts than the incoming mesh,
82  // then we need to "wrap" the other Mesh's processor ids to fit
83  // within our range. This can happen, for example, while stitching
84  // ReplicatedMeshes with small numbers of elements in parallel...
85  bool wrap_proc_ids = (_n_parts < other_mesh._n_parts);
86 
87  // We're assuming our subclass data needs no copy
88  libmesh_assert_equal_to (_is_prepared, other_mesh._is_prepared);
89 
90  // We're assuming the other mesh has proper element number ordering,
91  // so that we add parents before their children, and that the other
92  // mesh is consistently partitioned.
93 #ifdef DEBUG
95  MeshTools::libmesh_assert_valid_procids<Node>(other_mesh);
96 #endif
97 
98  //Copy in Nodes
99  {
100  //Preallocate Memory if necessary
101  this->reserve_nodes(other_mesh.n_nodes());
102 
103  for (const auto & oldn : other_mesh.node_ptr_range())
104  {
105  processor_id_type added_pid = cast_int<processor_id_type>
106  (wrap_proc_ids ? oldn->processor_id() % _n_parts : oldn->processor_id());
107 
108  // Add new nodes in old node Point locations
109  Node * newn =
110  this->add_point(*oldn,
111  oldn->id() + node_id_offset,
112  added_pid);
113 
114  newn->add_extra_integers(n_new_node_ints);
115  for (unsigned int i = 0; i != n_old_node_ints; ++i)
116  newn->set_extra_integer(extra_int_maps.second[i],
117  oldn->get_extra_integer(i));
118 
119 #ifdef LIBMESH_ENABLE_UNIQUE_ID
120  newn->set_unique_id() =
121  oldn->unique_id() + unique_id_offset;
122 #endif
123  }
124  }
125 
126  //Copy in Elements
127  {
128  //Preallocate Memory if necessary
129  this->reserve_elem(other_mesh.n_elem());
130 
131  // Declare a map linking old and new elements, needed to copy the neighbor lists
132  typedef std::unordered_map<const Elem *, Elem *> map_type;
133  map_type old_elems_to_new_elems;
134 
135  // Loop over the elements
136  for (const auto & old : other_mesh.element_ptr_range())
137  {
138  // Build a new element
139  Elem * newparent = old->parent() ?
140  this->elem_ptr(old->parent()->id() + element_id_offset) :
141  nullptr;
142  std::unique_ptr<Elem> ap = Elem::build(old->type(), newparent);
143  Elem * el = ap.release();
144 
145  el->subdomain_id() = old->subdomain_id();
146 
147 #ifdef LIBMESH_ENABLE_AMR
148  if (old->has_children())
149  for (unsigned int c = 0, nc = old->n_children(); c != nc; ++c)
150  if (old->child_ptr(c) == remote_elem)
151  el->add_child(const_cast<RemoteElem *>(remote_elem), c);
152 
153  //Create the parent's child pointers if necessary
154  if (newparent)
155  {
156  unsigned int oldc = old->parent()->which_child_am_i(old);
157  newparent->add_child(el, oldc);
158  }
159 
160  // Copy the refinement flags
161  el->set_refinement_flag(old->refinement_flag());
162 
163  // Use hack_p_level since we may not have sibling elements
164  // added yet
165  el->hack_p_level(old->p_level());
166 
167  el->set_p_refinement_flag(old->p_refinement_flag());
168 #endif // #ifdef LIBMESH_ENABLE_AMR
169 
170  //Assign all the nodes
171  for (auto i : el->node_index_range())
172  el->set_node(i) =
173  this->node_ptr(old->node_id(i) + node_id_offset);
174 
175  // And start it off with the same processor id (mod _n_parts).
176  el->processor_id() = cast_int<processor_id_type>
177  (wrap_proc_ids ? old->processor_id() % _n_parts : old->processor_id());
178 
179  // Give it the same element and unique ids
180  el->set_id(old->id() + element_id_offset);
181 
182  el->add_extra_integers(n_new_elem_ints);
183  for (unsigned int i = 0; i != n_old_elem_ints; ++i)
184  el->set_extra_integer(extra_int_maps.first[i],
185  old->get_extra_integer(i));
186 
187 #ifdef LIBMESH_ENABLE_UNIQUE_ID
188  el->set_unique_id() =
189  old->unique_id() + unique_id_offset;
190 #endif
191 
192  //Hold onto it
193  if (!skip_find_neighbors)
194  {
195  for (auto s : old->side_index_range())
196  if (old->neighbor_ptr(s) == remote_elem)
197  el->set_neighbor(s, const_cast<RemoteElem *>(remote_elem));
198  this->add_elem(el);
199  }
200  else
201  {
202  Elem * new_el = this->add_elem(el);
203  old_elems_to_new_elems[old] = new_el;
204  }
205  }
206 
207  // Loop (again) over the elements to fill in the neighbors
208  if (skip_find_neighbors)
209  {
210  old_elems_to_new_elems[remote_elem] = const_cast<RemoteElem*>(remote_elem);
211 
212  for (const auto & old_elem : other_mesh.element_ptr_range())
213  {
214  Elem * new_elem = old_elems_to_new_elems[old_elem];
215  for (auto s : old_elem->side_index_range())
216  {
217  const Elem * old_neighbor = old_elem->neighbor_ptr(s);
218  Elem * new_neighbor = old_elems_to_new_elems[old_neighbor];
219  new_elem->set_neighbor(s, new_neighbor);
220  }
221  }
222  }
223  }
224 
225  //Finally prepare the new Mesh for use. Keep the same numbering and
226  //partitioning for now.
227  this->allow_renumbering(false);
228  this->allow_remote_element_removal(false);
229 
230  // We should generally be able to skip *all* partitioning here
231  // because we're only adding one already-consistent mesh to another.
232  this->skip_partitioning(true);
233 
234  this->prepare_for_use(false, skip_find_neighbors);
235 
236  //But in the long term, use the same renumbering and partitioning
237  //policies as our source mesh.
238  this->allow_renumbering(other_mesh.allow_renumbering());
240  this->skip_partitioning(other_mesh._skip_all_partitioning);
242 }
243 
244 
245 
247 {
248  // this->clear (); // Nothing to clear at this level
249 
250  libmesh_exceptionless_assert (!libMesh::closed());
251 }
252 
253 
254 
255 
256 
257 void UnstructuredMesh::find_neighbors (const bool reset_remote_elements,
258  const bool reset_current_list)
259 {
260  // We might actually want to run this on an empty mesh
261  // (e.g. the boundary mesh for a nonexistent bcid!)
262  // libmesh_assert_not_equal_to (this->n_nodes(), 0);
263  // libmesh_assert_not_equal_to (this->n_elem(), 0);
264 
265  // This function must be run on all processors at once
266  parallel_object_only();
267 
268  LOG_SCOPE("find_neighbors()", "Mesh");
269 
270  //TODO:[BSK] This should be removed later?!
271  if (reset_current_list)
272  for (const auto & e : this->element_ptr_range())
273  for (auto s : e->side_index_range())
274  if (e->neighbor_ptr(s) != remote_elem || reset_remote_elements)
275  e->set_neighbor(s, nullptr);
276 
277  // Find neighboring elements by first finding elements
278  // with identical side keys and then check to see if they
279  // are neighbors
280  {
281  // data structures -- Use the hash_multimap if available
282  typedef unsigned int key_type;
283  typedef std::pair<Elem *, unsigned char> val_type;
284  typedef std::pair<key_type, val_type> key_val_pair;
285 
286  typedef std::unordered_multimap<key_type, val_type> map_type;
287 
288  // A map from side keys to corresponding elements & side numbers
289  map_type side_to_elem_map;
290 
291  // Pull objects out of the loop to reduce heap operations
292  std::unique_ptr<Elem> my_side, their_side;
293 
294  for (const auto & element : this->element_ptr_range())
295  {
296  for (auto ms : element->side_index_range())
297  {
298  next_side:
299  // If we haven't yet found a neighbor on this side, try.
300  // Even if we think our neighbor is remote, that
301  // information may be out of date.
302  if (element->neighbor_ptr(ms) == nullptr ||
303  element->neighbor_ptr(ms) == remote_elem)
304  {
305  // Get the key for the side of this element
306  const unsigned int key = element->key(ms);
307 
308  // Look for elements that have an identical side key
309  auto bounds = side_to_elem_map.equal_range(key);
310 
311  // May be multiple keys, check all the possible
312  // elements which _might_ be neighbors.
313  if (bounds.first != bounds.second)
314  {
315  // Get the side for this element
316  element->side_ptr(my_side, ms);
317 
318  // Look at all the entries with an equivalent key
319  while (bounds.first != bounds.second)
320  {
321  // Get the potential element
322  Elem * neighbor = bounds.first->second.first;
323 
324  // Get the side for the neighboring element
325  const unsigned int ns = bounds.first->second.second;
326  neighbor->side_ptr(their_side, ns);
327  //libmesh_assert(my_side.get());
328  //libmesh_assert(their_side.get());
329 
330  // If found a match with my side
331  //
332  // We need special tests here for 1D:
333  // since parents and children have an equal
334  // side (i.e. a node), we need to check
335  // ns != ms, and we also check level() to
336  // avoid setting our neighbor pointer to
337  // any of our neighbor's descendants
338  if ((*my_side == *their_side) &&
339  (element->level() == neighbor->level()) &&
340  ((element->dim() != 1) || (ns != ms)))
341  {
342  // So share a side. Is this a mixed pair
343  // of subactive and active/ancestor
344  // elements?
345  // If not, then we're neighbors.
346  // If so, then the subactive's neighbor is
347 
348  if (element->subactive() ==
349  neighbor->subactive())
350  {
351  // an element is only subactive if it has
352  // been coarsened but not deleted
353  element->set_neighbor (ms,neighbor);
354  neighbor->set_neighbor(ns,element);
355  }
356  else if (element->subactive())
357  {
358  element->set_neighbor(ms,neighbor);
359  }
360  else if (neighbor->subactive())
361  {
362  neighbor->set_neighbor(ns,element);
363  }
364  side_to_elem_map.erase (bounds.first);
365 
366  // get out of this nested crap
367  goto next_side;
368  }
369 
370  ++bounds.first;
371  }
372  }
373 
374  // didn't find a match...
375  // Build the map entry for this element
376  key_val_pair kvp;
377 
378  kvp.first = key;
379  kvp.second.first = element;
380  kvp.second.second = cast_int<unsigned char>(ms);
381  side_to_elem_map.insert (kvp);
382  }
383  }
384  }
385  }
386 
387 #ifdef LIBMESH_ENABLE_AMR
388 
416  const unsigned int n_levels = MeshTools::n_levels(*this);
417  for (unsigned int level = 1; level < n_levels; ++level)
418  {
419  for (auto & current_elem : as_range(level_elements_begin(level),
420  level_elements_end(level)))
421  {
422  libmesh_assert(current_elem);
423  Elem * parent = current_elem->parent();
424  libmesh_assert(parent);
425  const unsigned int my_child_num = parent->which_child_am_i(current_elem);
426 
427  for (auto s : current_elem->side_index_range())
428  {
429  if (current_elem->neighbor_ptr(s) == nullptr ||
430  (current_elem->neighbor_ptr(s) == remote_elem &&
431  parent->is_child_on_side(my_child_num, s)))
432  {
433  Elem * neigh = parent->neighbor_ptr(s);
434 
435  // If neigh was refined and had non-subactive children
436  // made remote earlier, then our current elem should
437  // actually have one of those remote children as a
438  // neighbor
439  if (neigh &&
440  (neigh->ancestor() ||
441  // If neigh has subactive children which should have
442  // matched as neighbors of the current element but
443  // did not, then those likewise must be remote
444  // children.
445  (current_elem->subactive() && neigh->has_children() &&
446  (neigh->level()+1) == current_elem->level())))
447  {
448 #ifdef DEBUG
449  // Let's make sure that "had children made remote"
450  // situation is actually the case
451  libmesh_assert(neigh->has_children());
452  bool neigh_has_remote_children = false;
453  for (auto & child : neigh->child_ref_range())
454  if (&child == remote_elem)
455  neigh_has_remote_children = true;
456  libmesh_assert(neigh_has_remote_children);
457 
458  // And let's double-check that we don't have
459  // a remote_elem neighboring an active local element
460  if (current_elem->active())
461  libmesh_assert_not_equal_to (current_elem->processor_id(),
462  this->processor_id());
463 #endif // DEBUG
464  neigh = const_cast<RemoteElem *>(remote_elem);
465  }
466  // If neigh and current_elem are more than one level
467  // apart, figuring out whether we have a remote
468  // neighbor here becomes much harder.
469  else if (neigh && (current_elem->subactive() &&
470  neigh->has_children()))
471  {
472  // Find the deepest descendant of neigh which
473  // we could consider for a neighbor. If we run
474  // out of neigh children, then that's our
475  // neighbor. If we find a potential neighbor
476  // with remote_children and we don't find any
477  // potential neighbors among its non-remote
478  // children, then our neighbor must be remote.
479  while (neigh != remote_elem &&
480  neigh->has_children())
481  {
482  bool found_neigh = false;
483  for (unsigned int c = 0, nc = neigh->n_children();
484  !found_neigh && c != nc; ++c)
485  {
486  Elem * child = neigh->child_ptr(c);
487  if (child == remote_elem)
488  continue;
489  for (auto ncn : child->neighbor_ptr_range())
490  {
491  if (ncn != remote_elem &&
492  ncn->is_ancestor_of(current_elem))
493  {
494  neigh = ncn;
495  found_neigh = true;
496  break;
497  }
498  }
499  }
500  if (!found_neigh)
501  neigh = const_cast<RemoteElem *>(remote_elem);
502  }
503  }
504  current_elem->set_neighbor(s, neigh);
505 #ifdef DEBUG
506  if (neigh != nullptr && neigh != remote_elem)
507  // We ignore subactive elements here because
508  // we don't care about neighbors of subactive element.
509  if ((!neigh->active()) && (!current_elem->subactive()))
510  {
511  libMesh::err << "On processor " << this->processor_id()
512  << std::endl;
513  libMesh::err << "Bad element ID = " << current_elem->id()
514  << ", Side " << s << ", Bad neighbor ID = " << neigh->id() << std::endl;
515  libMesh::err << "Bad element proc_ID = " << current_elem->processor_id()
516  << ", Bad neighbor proc_ID = " << neigh->processor_id() << std::endl;
517  libMesh::err << "Bad element size = " << current_elem->hmin()
518  << ", Bad neighbor size = " << neigh->hmin() << std::endl;
519  libMesh::err << "Bad element center = " << current_elem->centroid()
520  << ", Bad neighbor center = " << neigh->centroid() << std::endl;
521  libMesh::err << "ERROR: "
522  << (current_elem->active()?"Active":"Ancestor")
523  << " Element at level "
524  << current_elem->level() << std::endl;
525  libMesh::err << "with "
526  << (parent->active()?"active":
527  (parent->subactive()?"subactive":"ancestor"))
528  << " parent share "
529  << (neigh->subactive()?"subactive":"ancestor")
530  << " neighbor at level " << neigh->level()
531  << std::endl;
532  NameBasedIO(*this).write ("bad_mesh.gmv");
533  libmesh_error_msg("Problematic mesh written to bad_mesh.gmv.");
534  }
535 #endif // DEBUG
536  }
537  }
538 
539  // We can skip to the next element if we're full-dimension
540  // and therefore don't have any interior parents
541  if (current_elem->dim() >= LIBMESH_DIM)
542  continue;
543 
544  // We have no interior parents unless we can find one later
545  current_elem->set_interior_parent(nullptr);
546 
547  Elem * pip = parent->interior_parent();
548 
549  if (!pip)
550  continue;
551 
552  // If there's no interior_parent children, whether due to a
553  // remote element or a non-conformity, then there's no
554  // children to search.
555  if (pip == remote_elem || pip->active())
556  {
557  current_elem->set_interior_parent(pip);
558  continue;
559  }
560 
561  // For node comparisons we'll need a sensible tolerance
562  Real node_tolerance = current_elem->hmin() * TOLERANCE;
563 
564  // Otherwise our interior_parent should be a child of our
565  // parent's interior_parent.
566  for (auto & child : pip->child_ref_range())
567  {
568  // If we have a remote_elem, that might be our
569  // interior_parent. We'll set it provisionally now and
570  // keep trying to find something better.
571  if (&child == remote_elem)
572  {
573  current_elem->set_interior_parent
574  (const_cast<RemoteElem *>(remote_elem));
575  continue;
576  }
577 
578  bool child_contains_our_nodes = true;
579  for (auto & n : current_elem->node_ref_range())
580  {
581  bool child_contains_this_node = false;
582  for (auto & cn : child.node_ref_range())
583  if (cn.absolute_fuzzy_equals
584  (n, node_tolerance))
585  {
586  child_contains_this_node = true;
587  break;
588  }
589  if (!child_contains_this_node)
590  {
591  child_contains_our_nodes = false;
592  break;
593  }
594  }
595  if (child_contains_our_nodes)
596  {
597  current_elem->set_interior_parent(&child);
598  break;
599  }
600  }
601 
602  // We should have found *some* interior_parent at this
603  // point, whether semilocal or remote.
604  libmesh_assert(current_elem->interior_parent());
605  }
606  }
607 
608 #endif // AMR
609 
610 
611 #ifdef DEBUG
613  !reset_remote_elements);
615 #endif
616 }
617 
618 
619 
620 void UnstructuredMesh::read (const std::string & name,
621  void *,
622  bool skip_renumber_nodes_and_elements,
623  bool skip_find_neighbors)
624 {
625  // Set the skip_renumber_nodes_and_elements flag on all processors
626  // if necessary.
627  // This ensures that renumber_nodes_and_elements is *not* called
628  // during prepare_for_use() for certain types of mesh files.
629  // This is required in cases where there is an associated solution
630  // file which expects a certain ordering of the nodes.
631  if (name.rfind(".gmv") + 4 == name.size())
632  this->allow_renumbering(false);
633 
634  NameBasedIO(*this).read(name);
635 
636  if (skip_renumber_nodes_and_elements)
637  {
638  // Use MeshBase::allow_renumbering() yourself instead.
639  libmesh_deprecated();
640  this->allow_renumbering(false);
641  }
642 
643  // Done reading the mesh. Now prepare it for use.
644  this->prepare_for_use(/*skip_renumber (deprecated)*/ false,
645  skip_find_neighbors);
646 }
647 
648 
649 
650 void UnstructuredMesh::write (const std::string & name)
651 {
652  LOG_SCOPE("write()", "Mesh");
653 
654  NameBasedIO(*this).write(name);
655 }
656 
657 
658 
659 void UnstructuredMesh::write (const std::string & name,
660  const std::vector<Number> & v,
661  const std::vector<std::string> & vn)
662 {
663  LOG_SCOPE("write()", "Mesh");
664 
665  NameBasedIO(*this).write_nodal_data(name, v, vn);
666 }
667 
668 
669 
670 
671 
673  const processor_id_type pid) const
674 {
675 
676  // Issue a warning if the number the number of processors
677  // currently available is less that that requested for
678  // partitioning. This is not necessarily an error since
679  // you may run on one processor and still partition the
680  // mesh into several partitions.
681 #ifdef DEBUG
682  if (this->n_processors() < pid)
683  {
684  libMesh::out << "WARNING: You are creating a "
685  << "mesh for a processor id (="
686  << pid
687  << ") greater than "
688  << "the number of processors available for "
689  << "the calculation. (="
690  << this->n_processors()
691  << ")."
692  << std::endl;
693  }
694 #endif
695 
696  this->create_submesh (pid_mesh,
697  this->active_pid_elements_begin(pid),
698  this->active_pid_elements_end(pid));
699 }
700 
701 
702 
703 
704 
705 
706 
708  const const_element_iterator & it,
709  const const_element_iterator & it_end) const
710 {
711  // Just in case the subdomain_mesh already has some information
712  // in it, get rid of it.
713  new_mesh.clear();
714 
715  // If we're not serial, our submesh isn't either.
716  // There are no remote elements to delete on an empty mesh, but
717  // calling the method to do so marks the mesh as parallel.
718  if (!this->is_serial())
719  new_mesh.delete_remote_elements();
720 
721  // Fail if (*this == new_mesh), we cannot create a submesh inside ourself!
722  // This may happen if the user accidentally passes the original mesh into
723  // this function! We will check this by making sure we did not just
724  // clear ourself.
725  libmesh_assert_not_equal_to (this->n_nodes(), 0);
726  libmesh_assert_not_equal_to (this->n_elem(), 0);
727 
728  // Container to catch boundary IDs handed back by BoundaryInfo
729  std::vector<boundary_id_type> bc_ids;
730 
731  // Put any extra integers on the new mesh too
732  new_mesh.merge_extra_integer_names(*this);
733  const unsigned int n_node_ints = _node_integer_names.size(),
734  n_elem_ints = _elem_integer_names.size();
735 
736  for (const auto & old_elem : as_range(it, it_end))
737  {
738  // Add an equivalent element type to the new_mesh.
739  // Copy ids for this element.
740  Elem * new_elem = Elem::build(old_elem->type()).release();
741  new_elem->set_id() = old_elem->id();
742 #ifdef LIBMESH_ENABLE_UNIQUE_ID
743  new_elem->set_unique_id() = old_elem->unique_id();
744 #endif
745  new_elem->subdomain_id() = old_elem->subdomain_id();
746  new_elem->processor_id() = old_elem->processor_id();
747 
748  new_elem->add_extra_integers(n_elem_ints);
749  for (unsigned int i = 0; i != n_elem_ints; ++i)
750  new_elem->set_extra_integer(i, old_elem->get_extra_integer(i));
751 
752  new_mesh.add_elem (new_elem);
753 
754  libmesh_assert(new_elem);
755 
756  // Loop over the nodes on this element.
757  for (auto n : old_elem->node_index_range())
758  {
759  const dof_id_type this_node_id = old_elem->node_id(n);
760 
761  // Add this node to the new mesh if it's not there already
762  if (!new_mesh.query_node_ptr(this_node_id))
763  {
764  Node * newn =
765  new_mesh.add_point (old_elem->point(n),
766  this_node_id,
767  old_elem->node_ptr(n)->processor_id());
768 
769  newn->add_extra_integers(n_node_ints);
770  for (unsigned int i = 0; i != n_node_ints; ++i)
771  newn->set_extra_integer(i, old_elem->node_ptr(n)->get_extra_integer(i));
772 
773 #ifdef LIBMESH_ENABLE_UNIQUE_ID
774  newn->set_unique_id() = old_elem->node_ptr(n)->unique_id();
775 #endif
776  }
777 
778  // Define this element's connectivity on the new mesh
779  new_elem->set_node(n) = new_mesh.node_ptr(this_node_id);
780  }
781 
782  // Maybe add boundary conditions for this element
783  for (auto s : old_elem->side_index_range())
784  {
785  this->get_boundary_info().boundary_ids(old_elem, s, bc_ids);
786  new_mesh.get_boundary_info().add_side (new_elem, s, bc_ids);
787  }
788  } // end loop over elements
789 
790  // Prepare the new_mesh for use
791  new_mesh.prepare_for_use(/*skip_renumber =*/false);
792 }
793 
794 
795 
796 #ifdef LIBMESH_ENABLE_AMR
798 {
799  LOG_SCOPE ("contract()", "Mesh");
800 
801  // Flag indicating if this call actually changes the mesh
802  bool mesh_changed = false;
803 
804 #ifdef DEBUG
805  for (const auto & elem : this->element_ptr_range())
807 #endif
808 
809  // Loop over the elements.
810  for (auto & elem : this->element_ptr_range())
811  {
812  // Delete all the subactive ones
813  if (elem->subactive())
814  {
815  // No level-0 element should be subactive.
816  // Note that we CAN'T test elem->level(), as that
817  // touches elem->parent()->dim(), and elem->parent()
818  // might have already been deleted!
820 
821  // Delete the element
822  // This just sets a pointer to nullptr, and doesn't
823  // invalidate any iterators
824  this->delete_elem(elem);
825 
826  // the mesh has certainly changed
827  mesh_changed = true;
828  }
829  else
830  {
831  // Compress all the active ones
832  if (elem->active())
833  elem->contract();
834  else
836  }
837  }
838 
839  // Strip any newly-created nullptr voids out of the element array
841 
842  // FIXME: Need to understand why deleting subactive children
843  // invalidates the point locator. For now we will clear it explicitly
844  this->clear_point_locator();
845 
846  // Allow our GhostingFunctor objects to reinit if necessary.
847  for (auto & gf : as_range(this->ghosting_functors_begin(),
848  this->ghosting_functors_end()))
849  {
850  libmesh_assert(gf);
851  gf->mesh_reinit();
852  }
853 
854  return mesh_changed;
855 }
856 #endif // #ifdef LIBMESH_ENABLE_AMR
857 
858 
859 
861 {
862  /*
863  * when the mesh is not prepared,
864  * at least renumber the nodes and
865  * elements, so that the node ids
866  * are correct
867  */
868  if (!this->_is_prepared)
870 
871  START_LOG("all_first_order()", "Mesh");
872 
876  std::vector<bool> node_touched_by_me(this->max_node_id(), false);
877 
878  // Loop over the high-ordered elements.
879  // First make sure they _are_ indeed high-order, and then replace
880  // them with an equivalent first-order element.
881  for (auto & so_elem : element_ptr_range())
882  {
883  libmesh_assert(so_elem);
884 
885  /*
886  * build the first-order equivalent, add to
887  * the new_elements list.
888  */
889  Elem * lo_elem = Elem::build
891  (so_elem->type()), so_elem->parent()).release();
892 
893  const unsigned short n_sides = so_elem->n_sides();
894 
895  for (unsigned short s=0; s != n_sides; ++s)
896  if (so_elem->neighbor_ptr(s) == remote_elem)
897  lo_elem->set_neighbor(s, const_cast<RemoteElem *>(remote_elem));
898 
899 #ifdef LIBMESH_ENABLE_AMR
900  /*
901  * Reset the parent links of any child elements
902  */
903  if (so_elem->has_children())
904  for (unsigned int c = 0, nc = so_elem->n_children(); c != nc; ++c)
905  {
906  Elem * child = so_elem->child_ptr(c);
907  if (child != remote_elem)
908  child->set_parent(lo_elem);
909  lo_elem->add_child(child, c);
910  }
911 
912  /*
913  * Reset the child link of any parent element
914  */
915  if (so_elem->parent())
916  {
917  unsigned int c =
918  so_elem->parent()->which_child_am_i(so_elem);
919  lo_elem->parent()->replace_child(lo_elem, c);
920  }
921 
922  /*
923  * Copy as much data to the new element as makes sense
924  */
925  lo_elem->set_p_level(so_elem->p_level());
926  lo_elem->set_refinement_flag(so_elem->refinement_flag());
927  lo_elem->set_p_refinement_flag(so_elem->p_refinement_flag());
928 #endif
929 
930  libmesh_assert_equal_to (lo_elem->n_vertices(), so_elem->n_vertices());
931 
932  /*
933  * By definition the vertices of the linear and
934  * second order element are identically numbered.
935  * transfer these.
936  */
937  for (unsigned int v=0, snv=so_elem->n_vertices(); v < snv; v++)
938  {
939  lo_elem->set_node(v) = so_elem->node_ptr(v);
940  node_touched_by_me[lo_elem->node_id(v)] = true;
941  }
942 
943  /*
944  * find_neighbors relies on remote_elem neighbor links being
945  * properly maintained.
946  */
947  for (unsigned short s=0; s != n_sides; s++)
948  {
949  if (so_elem->neighbor_ptr(s) == remote_elem)
950  lo_elem->set_neighbor(s, const_cast<RemoteElem*>(remote_elem));
951  }
952 
960  (this->get_boundary_info(), so_elem, lo_elem);
961 
962  /*
963  * The new first-order element is ready.
964  * Inserting it into the mesh will replace and delete
965  * the second-order element.
966  */
967  lo_elem->set_id(so_elem->id());
968 #ifdef LIBMESH_ENABLE_UNIQUE_ID
969  lo_elem->set_unique_id() = so_elem->unique_id();
970 #endif
971  lo_elem->processor_id() = so_elem->processor_id();
972  lo_elem->subdomain_id() = so_elem->subdomain_id();
973  this->insert_elem(lo_elem);
974  }
975 
976  // Deleting nodes does not invalidate iterators, so this is safe.
977  for (const auto & node : this->node_ptr_range())
978  if (!node_touched_by_me[node->id()])
979  this->delete_node(node);
980 
981  // If crazy people applied boundary info to non-vertices and then
982  // deleted those non-vertices, we should make sure their boundary id
983  // caches are correct.
985 
986  STOP_LOG("all_first_order()", "Mesh");
987 
988  // On hanging nodes that used to also be second order nodes, we
989  // might now have an invalid nodal processor_id()
991 
992  // delete or renumber nodes if desired
993  this->prepare_for_use();
994 }
995 
996 
997 
998 void UnstructuredMesh::all_second_order (const bool full_ordered)
999 {
1000  // This function must be run on all processors at once
1001  parallel_object_only();
1002 
1003  /*
1004  * when the mesh is not prepared,
1005  * at least renumber the nodes and
1006  * elements, so that the node ids
1007  * are correct
1008  */
1009  if (!this->_is_prepared)
1010  this->renumber_nodes_and_elements ();
1011 
1012  /*
1013  * If the mesh is empty
1014  * then we have nothing to do
1015  */
1016  if (!this->n_elem())
1017  return;
1018 
1019  /*
1020  * If the mesh is already second order
1021  * then we have nothing to do.
1022  * We have to test for this in a round-about way to avoid
1023  * a bug on distributed parallel meshes with more processors
1024  * than elements.
1025  */
1026  bool already_second_order = false;
1027  if (this->elements_begin() != this->elements_end() &&
1028  (*(this->elements_begin()))->default_order() != FIRST)
1029  already_second_order = true;
1030  this->comm().max(already_second_order);
1031  if (already_second_order)
1032  return;
1033 
1034  START_LOG("all_second_order()", "Mesh");
1035 
1036  /*
1037  * this map helps in identifying second order
1038  * nodes. Namely, a second-order node:
1039  * - edge node
1040  * - face node
1041  * - bubble node
1042  * is uniquely defined through a set of adjacent
1043  * vertices. This set of adjacent vertices is
1044  * used to identify already added higher-order
1045  * nodes. We are safe to use node id's since we
1046  * make sure that these are correctly numbered.
1047  */
1048  std::map<std::vector<dof_id_type>, Node *> adj_vertices_to_so_nodes;
1049 
1050  /*
1051  * for speed-up of the \p add_point() method, we
1052  * can reserve memory. Guess the number of additional
1053  * nodes for different dimensions
1054  */
1055  switch (this->mesh_dimension())
1056  {
1057  case 1:
1058  /*
1059  * in 1D, there can only be order-increase from Edge2
1060  * to Edge3. Something like 1/2 of n_nodes() have
1061  * to be added
1062  */
1063  this->reserve_nodes(static_cast<unsigned int>
1064  (1.5*static_cast<double>(this->n_nodes())));
1065  break;
1066 
1067  case 2:
1068  /*
1069  * in 2D, either refine from Tri3 to Tri6 (double the nodes)
1070  * or from Quad4 to Quad8 (again, double) or Quad9 (2.25 that much)
1071  */
1072  this->reserve_nodes(static_cast<unsigned int>
1073  (2*static_cast<double>(this->n_nodes())));
1074  break;
1075 
1076 
1077  case 3:
1078  /*
1079  * in 3D, either refine from Tet4 to Tet10 (factor = 2.5) up to
1080  * Hex8 to Hex27 (something > 3). Since in 3D there _are_ already
1081  * quite some nodes, and since we do not want to overburden the memory by
1082  * a too conservative guess, use the lower bound
1083  */
1084  this->reserve_nodes(static_cast<unsigned int>
1085  (2.5*static_cast<double>(this->n_nodes())));
1086  break;
1087 
1088  default:
1089  // Hm?
1090  libmesh_error_msg("Unknown mesh dimension " << this->mesh_dimension());
1091  }
1092 
1093 
1094 
1095  /*
1096  * form a vector that will hold the node id's of
1097  * the vertices that are adjacent to the son-th
1098  * second-order node. Pull this outside of the
1099  * loop so that silly compilers don't repeatedly
1100  * create and destroy the vector.
1101  */
1102  std::vector<dof_id_type> adjacent_vertices_ids;
1103 
1111  n_partitioned_elem = 0;
1112  const processor_id_type my_pid = this->processor_id();
1113 
1121  it = elements_begin(),
1122  endit = elements_end();
1123 
1124  for (; it != endit; ++it)
1125  {
1126  // the linear-order element
1127  Elem * lo_elem = *it;
1128 
1129  libmesh_assert(lo_elem);
1130 
1131  // make sure it is linear order
1132  if (lo_elem->default_order() != FIRST)
1133  libmesh_error_msg("ERROR: This is not a linear element: type=" << lo_elem->type());
1134 
1135  // this does _not_ work for refined elements
1136  libmesh_assert_equal_to (lo_elem->level (), 0);
1137 
1138  const processor_id_type lo_pid = lo_elem->processor_id();
1139 
1140  if (lo_pid == DofObject::invalid_processor_id)
1142  else
1143  ++n_partitioned_elem;
1144 
1145  /*
1146  * build the second-order equivalent, add to
1147  * the new_elements list. Note that this here
1148  * is the only point where \p full_ordered
1149  * is necessary. The remaining code works well
1150  * for either type of second-order equivalent, e.g.
1151  * Hex20 or Hex27, as equivalents for Hex8
1152  */
1153  Elem * so_elem =
1155  full_ordered) ).release();
1156 
1157  libmesh_assert_equal_to (lo_elem->n_vertices(), so_elem->n_vertices());
1158 
1159 
1160  /*
1161  * By definition the vertices of the linear and
1162  * second order element are identically numbered.
1163  * transfer these.
1164  */
1165  for (unsigned int v=0, lnv=lo_elem->n_vertices(); v < lnv; v++)
1166  so_elem->set_node(v) = lo_elem->node_ptr(v);
1167 
1168  /*
1169  * Now handle the additional mid-side nodes. This
1170  * is simply handled through a map that remembers
1171  * the already-added nodes. This map maps the global
1172  * ids of the vertices (that uniquely define this
1173  * higher-order node) to the new node.
1174  * Notation: son = second-order node
1175  */
1176  const unsigned int son_begin = so_elem->n_vertices();
1177  const unsigned int son_end = so_elem->n_nodes();
1178 
1179 
1180  for (unsigned int son=son_begin; son<son_end; son++)
1181  {
1182  const unsigned int n_adjacent_vertices =
1183  so_elem->n_second_order_adjacent_vertices(son);
1184 
1185  adjacent_vertices_ids.resize(n_adjacent_vertices);
1186 
1187  for (unsigned int v=0; v<n_adjacent_vertices; v++)
1188  adjacent_vertices_ids[v] =
1189  so_elem->node_id( so_elem->second_order_adjacent_vertex(son,v) );
1190 
1191  /*
1192  * \p adjacent_vertices_ids is now in order of the current
1193  * side. sort it, so that comparisons with the
1194  * \p adjacent_vertices_ids created through other elements'
1195  * sides can match
1196  */
1197  std::sort(adjacent_vertices_ids.begin(),
1198  adjacent_vertices_ids.end());
1199 
1200 
1201  // does this set of vertices already have a mid-node added?
1202  auto pos = adj_vertices_to_so_nodes.equal_range (adjacent_vertices_ids);
1203 
1204  // no, not added yet
1205  if (pos.first == pos.second)
1206  {
1207  /*
1208  * for this set of vertices, there is no
1209  * second_order node yet. Add it.
1210  *
1211  * compute the location of the new node as
1212  * the average over the adjacent vertices.
1213  */
1214  Point new_location = this->point(adjacent_vertices_ids[0]);
1215  for (unsigned int v=1; v<n_adjacent_vertices; v++)
1216  new_location += this->point(adjacent_vertices_ids[v]);
1217 
1218  new_location /= static_cast<Real>(n_adjacent_vertices);
1219 
1220  /* Add the new point to the mesh.
1221  * If we are on a serialized mesh, then we're doing this
1222  * all in sync, and the node processor_id will be
1223  * consistent between processors.
1224  * If we are on a distributed mesh, we can fix
1225  * inconsistent processor ids later, but only if every
1226  * processor gives new nodes a *locally* consistent
1227  * processor id, so we'll give the new node the
1228  * processor id of an adjacent element for now and then
1229  * we'll update that later if appropriate.
1230  */
1231  Node * so_node = this->add_point
1232  (new_location, DofObject::invalid_id, lo_pid);
1233 
1234  /*
1235  * insert the new node with its defining vertex
1236  * set into the map, and relocate pos to this
1237  * new entry, so that the so_elem can use
1238  * \p pos for inserting the node
1239  */
1240  adj_vertices_to_so_nodes.insert(pos.first,
1241  std::make_pair(adjacent_vertices_ids,
1242  so_node));
1243 
1244  so_elem->set_node(son) = so_node;
1245  }
1246  // yes, already added.
1247  else
1248  {
1249  Node * so_node = pos.first->second;
1250  libmesh_assert(so_node);
1251 
1252  so_elem->set_node(son) = so_node;
1253 
1254  // We need to ensure that the processor who should own a
1255  // node *knows* they own the node. And because
1256  // Node::choose_processor_id() may depend on Node id,
1257  // which may not yet be authoritative, we still have to
1258  // use a dumb-but-id-independent partitioning heuristic.
1259  processor_id_type chosen_pid =
1260  std::min (so_node->processor_id(), lo_pid);
1261 
1262  // Plus, if we just discovered that we own this node,
1263  // then on a distributed mesh we need to make sure to
1264  // give it a valid id, not just a placeholder id!
1265  if (!this->is_replicated() &&
1266  so_node->processor_id() != my_pid &&
1267  chosen_pid == my_pid)
1268  this->own_node(*so_node);
1269 
1270  so_node->processor_id() = chosen_pid;
1271  }
1272  }
1273 
1274  /*
1275  * find_neighbors relies on remote_elem neighbor links being
1276  * properly maintained.
1277  */
1278  for (auto s : lo_elem->side_index_range())
1279  {
1280  if (lo_elem->neighbor_ptr(s) == remote_elem)
1281  so_elem->set_neighbor(s, const_cast<RemoteElem*>(remote_elem));
1282  }
1283 
1296  (this->get_boundary_info(), lo_elem, so_elem);
1297 
1298  /*
1299  * The new second-order element is ready.
1300  * Inserting it into the mesh will replace and delete
1301  * the first-order element.
1302  */
1303  so_elem->set_id(lo_elem->id());
1304 #ifdef LIBMESH_ENABLE_UNIQUE_ID
1305  so_elem->set_unique_id() = lo_elem->unique_id();
1306 #endif
1307  so_elem->processor_id() = lo_pid;
1308  so_elem->subdomain_id() = lo_elem->subdomain_id();
1309  this->insert_elem(so_elem);
1310  }
1311 
1312  // we can clear the map
1313  adj_vertices_to_so_nodes.clear();
1314 
1315 
1316  STOP_LOG("all_second_order()", "Mesh");
1317 
1318  // On a DistributedMesh our ghost node processor ids may be bad,
1319  // the ids of nodes touching remote elements may be inconsistent,
1320  // unique_ids of newly added non-local nodes remain unset, and our
1321  // partitioning of new nodes may not be well balanced.
1322  //
1323  // make_nodes_parallel_consistent() will fix all this.
1324  if (!this->is_replicated())
1325  {
1326  dof_id_type max_unpartitioned_elem = n_unpartitioned_elem;
1327  this->comm().max(max_unpartitioned_elem);
1328  if (max_unpartitioned_elem)
1329  {
1330  // We'd better be effectively serialized here. In theory we
1331  // could support more complicated cases but in practice we
1332  // only support "completely partitioned" and/or "serialized"
1333  if (!this->comm().verify(n_unpartitioned_elem) ||
1334  !this->comm().verify(n_partitioned_elem) ||
1335  !this->is_serial())
1336  libmesh_not_implemented();
1337  }
1338  else
1339  {
1340  MeshCommunication().make_nodes_parallel_consistent (*this);
1341  }
1342  }
1343 
1344  // renumber nodes, elements etc
1345  this->prepare_for_use(/*skip_renumber =*/ false);
1346 }
1347 
1348 } // namespace libMesh
libMesh::MeshBase::MeshCommunication
friend class MeshCommunication
Make the MeshCommunication class a friend so that it can directly broadcast *_integer_names.
Definition: mesh_base.h:1857
libMesh::MeshBase::_is_prepared
bool _is_prepared
Flag indicating if the mesh has been prepared for use.
Definition: mesh_base.h:1698
libMesh::MeshBase::ghosting_functors_begin
std::set< GhostingFunctor * >::const_iterator ghosting_functors_begin() const
Beginning of range of ghosting functors.
Definition: mesh_base.h:1113
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::BoundaryInfo::boundary_ids
std::vector< boundary_id_type > boundary_ids(const Node *node) const
Definition: boundary_info.C:985
libMesh::Elem::child_ptr
const Elem * child_ptr(unsigned int i) const
Definition: elem.h:2567
libMesh::MeshBase::ghosting_functors_end
std::set< GhostingFunctor * >::const_iterator ghosting_functors_end() const
End of range of ghosting functors.
Definition: mesh_base.h:1119
libMesh::MeshBase::allow_renumbering
bool allow_renumbering() const
Definition: mesh_base.h:1026
libMesh::MeshBase::element_iterator
The definition of the element_iterator struct.
Definition: mesh_base.h:1873
libMesh::Elem::n_second_order_adjacent_vertices
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int n) const
Definition: elem.C:2343
libMesh::MeshBase::delete_node
virtual void delete_node(Node *n)=0
Removes the Node n from the mesh.
libMesh::MeshBase::reserve_nodes
virtual void reserve_nodes(const dof_id_type nn)=0
Reserves space for a known number of nodes.
libMesh::Elem::replace_child
void replace_child(Elem *elem, unsigned int c)
Replaces the child pointer at the specified index in the child array.
Definition: elem.C:1430
libMesh::Elem::set_p_refinement_flag
void set_p_refinement_flag(const RefinementState pflag)
Sets the value of the p-refinement flag for the element.
Definition: elem.h:2638
libMesh::NameBasedIO::write
virtual void write(const std::string &mesh_file) override
This method implements writing a mesh to a specified file.
Definition: namebased_io.C:285
libMesh::MeshBase::merge_extra_integer_names
std::pair< std::vector< unsigned int >, std::vector< unsigned int > > merge_extra_integer_names(const MeshBase &other)
Merge extra-integer arrays from an other mesh.
Definition: mesh_base.C:944
libMesh::UnstructuredMesh::find_neighbors
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true) override
Other functions from MeshBase requiring re-definition.
Definition: unstructured_mesh.C:257
libMesh::Elem::set_parent
void set_parent(Elem *p)
Sets the pointer to the element's parent.
Definition: elem.h:2450
libMesh::MeshBase::active_pid_elements_end
virtual element_iterator active_pid_elements_end(processor_id_type proc_id)=0
libMesh::unique_id_type
uint8_t unique_id_type
Definition: id_types.h:86
libMesh::MeshBase::get_boundary_info
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:132
libMesh::Elem::set_interior_parent
void set_interior_parent(Elem *p)
Sets the pointer to the element's interior_parent.
Definition: elem.C:801
libMesh::MeshBase::is_serial
virtual bool is_serial() const
Definition: mesh_base.h:159
libMesh::Elem::level
unsigned int level() const
Definition: elem.h:2478
libMesh::Elem::child_ref_range
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:1839
libMesh::Elem::n_nodes
virtual unsigned int n_nodes() const =0
libMesh::UnstructuredMesh::create_pid_mesh
void create_pid_mesh(UnstructuredMesh &pid_mesh, const processor_id_type pid) const
Generates a new mesh containing all the elements which are assigned to processor pid.
Definition: unstructured_mesh.C:672
libMesh::MeshBase::point
virtual const Point & point(const dof_id_type i) const =0
libMesh::MeshBase::delete_elem
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
libMesh::Elem::contract
void contract()
Contract an active element, i.e.
Definition: elem_refinement.C:230
libMesh::Elem::ancestor
bool ancestor() const
Definition: elem.C:1350
libMesh::MeshTools::libmesh_assert_valid_amr_elem_ids
void libmesh_assert_valid_amr_elem_ids(const MeshBase &mesh)
A function for verifying that ids of elements are correctly sorted for AMR (parents have lower ids th...
Definition: mesh_tools.C:1315
libMesh::MeshBase::n_elem
virtual dof_id_type n_elem() const =0
libMesh::DofObject::set_id
dof_id_type & set_id()
Definition: dof_object.h:776
libMesh::UnstructuredMesh::copy_nodes_and_elements
virtual void copy_nodes_and_elements(const UnstructuredMesh &other_mesh, const bool skip_find_neighbors=false, dof_id_type element_id_offset=0, dof_id_type node_id_offset=0, unique_id_type unique_id_offset=0)
Deep copy of nodes and elements from another unstructured mesh class (used by subclass copy construct...
Definition: unstructured_mesh.C:61
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::Elem::set_p_level
void set_p_level(const unsigned int p)
Sets the value of the p-refinement level for the element.
Definition: elem_refinement.C:41
libMesh::MeshTools::libmesh_assert_valid_neighbors
void libmesh_assert_valid_neighbors(const MeshBase &mesh, bool assert_valid_remote_elems=true)
A function for verifying that neighbor connectivity is correct (each element is a neighbor of or desc...
Definition: mesh_tools.C:2061
libMesh::MeshBase::_skip_all_partitioning
bool _skip_all_partitioning
If this is true then no partitioning should be done.
Definition: mesh_base.h:1739
libMesh::Elem::add_child
void add_child(Elem *elem)
Adds a child pointer to the array of children of this element.
Definition: elem.C:1384
libMesh::MeshBase::_n_parts
unsigned int _n_parts
The number of partitions the mesh has.
Definition: mesh_base.h:1680
libMesh::TOLERANCE
static const Real TOLERANCE
Definition: libmesh_common.h:128
libMesh::DofObject::add_extra_integers
void add_extra_integers(const unsigned int n_integers)
Assigns a set of extra integers to this DofObject.
Definition: dof_object.C:503
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
libMesh::Elem::set_neighbor
void set_neighbor(const unsigned int i, Elem *n)
Assigns n as the neighbor.
Definition: elem.h:2105
libMesh::Elem::neighbor_ptr_range
SimpleRange< NeighborPtrIter > neighbor_ptr_range()
Returns a range with all neighbors of an element, usable in range-based for loops.
Definition: elem.h:2917
libMesh::MeshBase::node_ptr
virtual const Node * node_ptr(const dof_id_type i) const =0
libMesh::MeshBase::mesh_dimension
unsigned int mesh_dimension() const
Definition: mesh_base.C:135
libMesh::DofObject::set_unique_id
unique_id_type & set_unique_id()
Definition: dof_object.h:797
libMesh::MeshBase::max_node_id
virtual dof_id_type max_node_id() const =0
libMesh::MeshBase::active_pid_elements_begin
virtual element_iterator active_pid_elements_begin(processor_id_type proc_id)=0
libMesh::DofObject::processor_id
processor_id_type processor_id() const
Definition: dof_object.h:829
libMesh::MeshBase::elem_ptr
virtual const Elem * elem_ptr(const dof_id_type i) const =0
libMesh::MeshBase::elements_begin
virtual element_iterator elements_begin()=0
Iterate over all the elements in the Mesh.
libMesh::Elem::active
bool active() const
Definition: elem.h:2345
libMesh::MeshTools::n_levels
unsigned int n_levels(const MeshBase &mesh)
Definition: mesh_tools.C:656
libMesh::Elem::centroid
virtual Point centroid() const
Definition: elem.C:345
libMesh::BoundaryInfo::copy_boundary_ids
void copy_boundary_ids(const BoundaryInfo &old_boundary_info, const Elem *const old_elem, const Elem *const new_elem)
Definition: boundary_info.C:1328
libMesh::UnstructuredMesh::all_first_order
virtual void all_first_order() override
Converts a mesh with higher-order elements into a mesh with linear elements.
Definition: unstructured_mesh.C:860
libMesh::UnstructuredMesh::~UnstructuredMesh
virtual ~UnstructuredMesh()
Destructor.
Definition: unstructured_mesh.C:246
libMesh::UnstructuredMesh::write
virtual void write(const std::string &name) override
Write the file specified by name.
Definition: unstructured_mesh.C:650
libMesh::Elem::second_order_adjacent_vertex
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const
Definition: elem.C:2351
libMesh::MeshBase::element_ptr_range
virtual SimpleRange< element_iterator > element_ptr_range()=0
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::MeshBase::own_node
virtual void own_node(Node &)
Takes ownership of node n on this partition of a distributed mesh, by setting n.processor_id() to thi...
Definition: mesh_base.h:656
libMesh::Elem::subactive
bool subactive() const
Definition: elem.h:2363
libMesh::MeshBase
This is the MeshBase class.
Definition: mesh_base.h:78
libMesh::MeshBase::level_elements_begin
virtual element_iterator level_elements_begin(unsigned int level)=0
Iterate over elements of a given level.
libMesh::MeshBase::_elem_integer_names
std::vector< std::string > _elem_integer_names
The array of names for integer data associated with each element in the mesh.
Definition: mesh_base.h:1780
libMesh::ParallelObject::n_processors
processor_id_type n_processors() const
Definition: parallel_object.h:100
libMesh::MeshBase::node_ptr_range
virtual SimpleRange< node_iterator > node_ptr_range()=0
libMesh::UnstructuredMesh::contract
virtual bool contract() override
Delete subactive (i.e.
Definition: unstructured_mesh.C:797
libMesh::MeshBase::elem
virtual const Elem * elem(const dof_id_type i) const
Definition: mesh_base.h:554
libMesh::MeshBase::clear_point_locator
void clear_point_locator()
Releases the current PointLocator object.
Definition: mesh_base.C:696
libMesh::Elem::first_order_equivalent_type
static ElemType first_order_equivalent_type(const ElemType et)
Definition: elem.C:2369
libMesh::NameBasedIO::read
virtual void read(const std::string &mesh_file) override
This method implements reading a mesh from a specified file.
Definition: namebased_io.C:62
libMesh::ParallelObject::processor_id
processor_id_type processor_id() const
Definition: parallel_object.h:106
libMesh::DofObject::invalid_id
static const dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition: dof_object.h:421
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::Elem::side_ptr
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=0
libMesh::UnstructuredMesh::read
virtual void read(const std::string &name, void *mesh_data=nullptr, bool skip_renumber_nodes_and_elements=false, bool skip_find_neighbors=false) override
Reads the file specified by name.
Definition: unstructured_mesh.C:620
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::MeshBase::skip_noncritical_partitioning
bool skip_noncritical_partitioning() const
Definition: mesh_base.h:1061
libMesh::MeshBase::insert_elem
virtual Elem * insert_elem(Elem *e)=0
Insert elem e to the element array, preserving its id and replacing/deleting any existing element wit...
libMesh::Elem::n_vertices
virtual unsigned int n_vertices() const =0
libMesh::Node
A Node is like a Point, but with more information.
Definition: node.h:52
libMesh::Elem::default_order
virtual Order default_order() const =0
libMesh::MeshBase::node
virtual const Node & node(const dof_id_type i) const
Definition: mesh_base.h:471
libMesh::as_range
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
libMesh::Elem::is_child_on_side
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const =0
libMesh::DofObject::unique_id
unique_id_type unique_id() const
Definition: dof_object.h:784
libMesh::BoundaryInfo::regenerate_id_sets
void regenerate_id_sets()
Clears and regenerates the cached sets of ids.
Definition: boundary_info.C:159
libMesh::MeshBase::const_element_iterator
The definition of the const_element_iterator struct.
Definition: mesh_base.h:1891
libMesh::UnstructuredMesh::UnstructuredMesh
UnstructuredMesh(const Parallel::Communicator &comm_in, unsigned char dim=1)
Constructor.
Definition: unstructured_mesh.C:52
libMesh::MeshBase::_node_integer_names
std::vector< std::string > _node_integer_names
The array of names for integer data associated with each node in the mesh.
Definition: mesh_base.h:1786
libMesh::MeshBase::delete_remote_elements
virtual void delete_remote_elements()
When supported, deletes all nonlocal elements of the mesh except for "ghosts" which touch a local ele...
Definition: mesh_base.h:201
libMesh::Elem::set_node
virtual Node *& set_node(const unsigned int i)
Definition: elem.h:2059
libMesh::UnstructuredMesh
The UnstructuredMesh class is derived from the MeshBase class.
Definition: unstructured_mesh.h:48
libMesh::MeshBase::renumber_nodes_and_elements
virtual void renumber_nodes_and_elements()=0
After partitioning a mesh it is useful to renumber the nodes and elements so that they lie in contigu...
libMesh::Elem::parent
const Elem * parent() const
Definition: elem.h:2434
libMesh::MeshBase::n_nodes
virtual dof_id_type n_nodes() const =0
libMesh::initialized
bool initialized()
Checks that library initialization has been done.
Definition: libmesh.C:265
libMesh::Elem::interior_parent
const Elem * interior_parent() const
Definition: elem.C:749
libMesh::Elem::n_children
virtual unsigned int n_children() const =0
libMesh::Elem::is_ancestor_of
bool is_ancestor_of(const Elem *descendant) const
Definition: elem.h:2413
libMesh::MeshBase::add_elem
virtual Elem * add_elem(Elem *e)=0
Add elem e to the end of the element array.
libMesh::Elem::hmin
virtual Real hmin() const
Definition: elem.C:359
libMesh::Partitioner::set_node_processor_ids
static void set_node_processor_ids(MeshBase &mesh)
This function is called after partitioning to set the processor IDs for the nodes.
Definition: partitioner.C:691
libMesh::MeshBase::n_unpartitioned_elem
dof_id_type n_unpartitioned_elem() const
Definition: mesh_base.h:409
libMesh::Elem::subdomain_id
subdomain_id_type subdomain_id() const
Definition: elem.h:2069
libMesh::DofObject::id
dof_id_type id() const
Definition: dof_object.h:767
libMesh::MeshBase::elements_end
virtual element_iterator elements_end()=0
libMesh::UnstructuredMesh::all_second_order
virtual void all_second_order(const bool full_ordered=true) override
Converts a (conforming, non-refined) mesh with linear elements into a mesh with second-order elements...
Definition: unstructured_mesh.C:998
libMesh::Elem::has_children
bool has_children() const
Definition: elem.h:2383
libMesh::Elem::side_index_range
IntRange< unsigned short > side_index_range() const
Definition: elem.h:2188
libMesh::MeshTools::libmesh_assert_valid_amr_interior_parents
void libmesh_assert_valid_amr_interior_parents(const MeshBase &mesh)
A function for verifying that any interior_parent pointers on elements are consistent with AMR (paren...
Definition: mesh_tools.C:1335
libMesh::DofObject::invalid_processor_id
static const processor_id_type invalid_processor_id
An invalid processor_id to distinguish DoFs that have not been assigned to a processor.
Definition: dof_object.h:432
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
libMesh::Elem::second_order_equivalent_type
static ElemType second_order_equivalent_type(const ElemType et, const bool full_ordered=true)
Definition: elem.C:2432
libMesh::UnstructuredMesh::create_submesh
void create_submesh(UnstructuredMesh &new_mesh, const const_element_iterator &it, const const_element_iterator &it_end) const
Constructs a mesh called "new_mesh" from the current mesh by iterating over the elements between it a...
Definition: unstructured_mesh.C:707
libMesh::MeshBase::allow_remote_element_removal
bool allow_remote_element_removal() const
Definition: mesh_base.h:1035
libMesh::MeshBase::allow_remote_element_removal
void allow_remote_element_removal(bool allow)
If false is passed in then this mesh will no longer have remote elements deleted when being prepared ...
Definition: mesh_base.h:1034
libMesh::Elem::set_refinement_flag
void set_refinement_flag(const RefinementState rflag)
Sets the value of the refinement flag for the element.
Definition: elem.h:2622
libMesh::MeshBase::add_point
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
Add a new Node at Point p to the end of the vertex array, with processor_id procid.
libMesh::NameBasedIO
This class supports simple reads and writes in any libMesh-supported format, by dispatching to one of...
Definition: namebased_io.h:44
libMesh::MeshBase::level_elements_end
virtual element_iterator level_elements_end(unsigned int level)=0
libMesh::err
OStreamProxy err
libMesh::Elem::neighbor_ptr
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2085
libMesh::MeshBase::allow_renumbering
void allow_renumbering(bool allow)
If false is passed in then this mesh will no longer be renumbered when being prepared for use.
Definition: mesh_base.h:1025
libMesh::Elem::node_id
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1977
libMesh::DofObject::set_extra_integer
void set_extra_integer(const unsigned int index, const dof_id_type value)
Sets the value on this object of the extra integer associated with index, which should have been obta...
Definition: dof_object.h:1010
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::MeshBase::prepare_for_use
void prepare_for_use(const bool skip_renumber_nodes_and_elements=false, const bool skip_find_neighbors=false)
Prepare a newly ecreated (or read) mesh for use.
Definition: mesh_base.C:318
libMesh::MeshBase::clear
virtual void clear()
Deletes all the element and node data that is currently stored.
Definition: mesh_base.C:429
libMesh::Elem::build
static std::unique_ptr< Elem > build(const ElemType type, Elem *p=nullptr)
Definition: elem.C:246
libMesh::MeshBase::query_node_ptr
virtual const Node * query_node_ptr(const dof_id_type i) const =0
libMesh::out
OStreamProxy out
libMesh::Elem::node_ptr
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2009
libMesh::MeshBase::_skip_noncritical_partitioning
bool _skip_noncritical_partitioning
If this is true then no partitioning should be done with the possible exception of orphaned nodes.
Definition: mesh_base.h:1734
libMesh::BoundaryInfo::add_side
void add_side(const dof_id_type elem, const unsigned short int side, const boundary_id_type id)
Add side side of element number elem with boundary id id to the boundary information data structure.
Definition: boundary_info.C:886
libMesh::Elem::type
virtual ElemType type() const =0
libMesh::FIRST
Definition: enum_order.h:42
libMesh::MeshBase::skip_partitioning
bool skip_partitioning() const
Definition: mesh_base.h:1078
libMesh::remote_elem
const RemoteElem * remote_elem
Definition: remote_elem.C:57
libMesh::MeshBase::reserve_elem
virtual void reserve_elem(const dof_id_type ne)=0
Reserves space for a known number of elements.
libMesh::Elem::which_child_am_i
unsigned int which_child_am_i(const Elem *e) const
Definition: elem.h:2596
libMesh::Quality::name
std::string name(const ElemQuality q)
This function returns a string containing some name for q.
Definition: elem_quality.C:42
libMesh::MeshBase::is_replicated
virtual bool is_replicated() const
Definition: mesh_base.h:181
libMesh::NameBasedIO::write_nodal_data
virtual void write_nodal_data(const std::string &, const std::vector< Number > &, const std::vector< std::string > &) override
This method implements writing a mesh with nodal data to a specified file where the nodal data and va...
Definition: namebased_io.C:441
libMesh::closed
bool closed()
Checks that the library has been closed.
Definition: libmesh.C:272