libMesh
Namespaces | Classes | Functions
libMesh::MeshTools Namespace Reference

Utility functions for operations on a Mesh object. More...

Namespaces

 Generation
 Tools for Mesh generation.
 
 Modification
 Tools for Mesh modification.
 
 Private
 
 Subdivision
 Utility functions for subdivision surface operations on a Mesh.
 

Classes

class  SidesToElemMap
 This class implements a generalization of the MeshTools::build_nodes_to_elem_map() function, but rather than being a standalone function taking a std::unordered_map argument, we define a class with APIs for both building the underlying map data structure and querying its contents. More...
 

Functions

dof_id_type total_weight (const MeshBase &mesh)
 
dof_id_type weight (const MeshBase &mesh, const processor_id_type pid)
 
dof_id_type weight (const MeshBase &mesh)
 
void build_nodes_to_elem_map (const MeshBase &mesh, std::vector< std::vector< dof_id_type >> &nodes_to_elem_map)
 After calling this function the input vector nodes_to_elem_map will contain the node to element connectivity. More...
 
void build_nodes_to_elem_map (const MeshBase &mesh, std::vector< std::vector< const Elem *>> &nodes_to_elem_map)
 The same, except element pointers are returned instead of indices. More...
 
void build_nodes_to_elem_map (const MeshBase &mesh, std::unordered_map< dof_id_type, std::vector< dof_id_type >> &nodes_to_elem_map)
 After calling this function the input map nodes_to_elem_map will contain the node to element connectivity. More...
 
void build_nodes_to_elem_map (const MeshBase &mesh, std::unordered_map< dof_id_type, std::vector< const Elem *>> &nodes_to_elem_map)
 The same, except element pointers are returned instead of indices. More...
 
std::unordered_set< dof_id_typefind_boundary_nodes (const MeshBase &mesh)
 Calling this function on a 2D mesh will convert all the elements to triangles. More...
 
std::unordered_set< dof_id_typefind_block_boundary_nodes (const MeshBase &mesh)
 Returns a std::set containing Node IDs for all of the block boundary nodes. More...
 
libMesh::BoundingBox create_bounding_box (const MeshBase &mesh)
 
Sphere bounding_sphere (const MeshBase &mesh)
 
libMesh::BoundingBox create_nodal_bounding_box (const MeshBase &mesh)
 
libMesh::BoundingBox create_local_bounding_box (const MeshBase &mesh)
 
libMesh::BoundingBox create_processor_bounding_box (const MeshBase &mesh, const processor_id_type pid)
 
Sphere processor_bounding_sphere (const MeshBase &mesh, const processor_id_type pid)
 
libMesh::BoundingBox create_subdomain_bounding_box (const MeshBase &mesh, const subdomain_id_type sid)
 
Sphere subdomain_bounding_sphere (const MeshBase &mesh, const subdomain_id_type sid)
 
void elem_types (const MeshBase &mesh, std::vector< ElemType > &et)
 Fills in a vector of all element types in the mesh. More...
 
dof_id_type n_elem_of_type (const MeshBase &mesh, const ElemType type)
 
dof_id_type n_active_elem_of_type (const MeshBase &mesh, const ElemType type)
 
dof_id_type n_non_subactive_elem_of_type_at_level (const MeshBase &mesh, const ElemType type, const unsigned int level)
 
unsigned int n_levels (const MeshBase &mesh)
 
unsigned int n_local_levels (const MeshBase &mesh)
 
unsigned int n_active_levels (const MeshBase &mesh)
 
unsigned int n_active_local_levels (const MeshBase &mesh)
 
unsigned int n_p_levels (const MeshBase &mesh)
 
unsigned int paranoid_n_levels (const MeshBase &mesh)
 
dof_id_type n_connected_components (const MeshBase &mesh, Real constraint_tol=0)
 
void get_not_subactive_node_ids (const MeshBase &mesh, std::set< dof_id_type > &not_subactive_node_ids)
 Builds a set of node IDs for nodes which belong to non-subactive elements. More...
 
dof_id_type n_elem (const MeshBase::const_element_iterator &begin, const MeshBase::const_element_iterator &end)
 Count up the number of elements of a specific type (as defined by an iterator range). More...
 
dof_id_type n_nodes (const MeshBase::const_node_iterator &begin, const MeshBase::const_node_iterator &end)
 Count up the number of nodes of a specific type (as defined by an iterator range). More...
 
Real volume (const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
 Find the total volume of a mesh (interpreting that as area for dim = 2, or total arc length for dim = 1, or number of NodeElem in the mesh for dim = 0). More...
 
void find_nodal_neighbors (const MeshBase &mesh, const Node &n, const std::vector< std::vector< const Elem *>> &nodes_to_elem_map, std::vector< const Node *> &neighbors)
 Given a mesh and a node in the mesh, the vector will be filled with every node directly attached to the given one. More...
 
void find_nodal_neighbors (const MeshBase &mesh, const Node &n, const std::unordered_map< dof_id_type, std::vector< const Elem *>> &nodes_to_elem_map, std::vector< const Node *> &neighbors)
 Given a mesh and a node in the mesh, the vector will be filled with every node directly attached to the given one. More...
 
void find_nodal_or_face_neighbors (const MeshBase &mesh, const Node &node, const std::unordered_map< dof_id_type, std::vector< const Elem *>> &nodes_to_elem_map, std::vector< const Node *> &neighbors)
 Given a mesh and a node in the mesh, the vector will be filled with every node directly attached to the given one. More...
 
void find_hanging_nodes_and_parents (const MeshBase &mesh, std::map< dof_id_type, std::vector< dof_id_type >> &hanging_nodes)
 Given a mesh hanging_nodes will be filled with an associative array keyed off the global id of all the hanging nodes in the mesh. More...
 
void correct_node_proc_ids (MeshBase &)
 Changes the processor ids on each node so be the same as the id of the lowest element touching that node. More...
 
void clear_spline_nodes (MeshBase &)
 Remove spline node (for IsoGeometric Analysis meshes) elements and nodes and constraints from the mesh. More...
 
bool valid_is_prepared (const MeshBase &mesh)
 A function for testing whether a mesh's cached is_prepared() setting is not a false positive. More...
 
template<>
void libmesh_assert_topology_consistent_procids< Elem > (const MeshBase &mesh)
 
template<>
void libmesh_assert_topology_consistent_procids< Node > (const MeshBase &mesh)
 
template<>
void libmesh_assert_parallel_consistent_procids< Elem > (const MeshBase &mesh)
 
template<>
void libmesh_assert_parallel_consistent_procids< Node > (const MeshBase &mesh)
 
void libmesh_assert_equal_n_systems (const MeshBase &mesh)
 The following functions, only available in builds with NDEBUG undefined, are for asserting internal consistency that we hope should never be broken in opt. More...
 
void libmesh_assert_old_dof_objects (const MeshBase &mesh)
 A function for testing that all non-recently-created DofObjects within a mesh have old_dof_object data. More...
 
void libmesh_assert_valid_node_pointers (const MeshBase &mesh)
 A function for walking across the mesh to try and ferret out invalidated or misassigned pointers. More...
 
void libmesh_assert_valid_remote_elems (const MeshBase &mesh)
 A function for verifying that active local elements' neighbors are never remote elements. More...
 
void libmesh_assert_valid_elem_ids (const MeshBase &mesh)
 A function for verifying that ids and processor assignment of elements are correctly sorted (monotone increasing) More...
 
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 than children) More...
 
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 (parents' interior_parents are interior_parents' parents) More...
 
void libmesh_assert_contiguous_dof_ids (const MeshBase &mesh, unsigned int sysnum)
 A function for verifying that degree of freedom indexes are contiguous on each processor, as is required by libMesh numeric classes. More...
 
template<typename DofObjectSubclass >
void libmesh_assert_topology_consistent_procids (const MeshBase &mesh)
 A function for verifying that processor assignment is topologically consistent on nodes (each node part of an active element on its processor) or elements (each parent has the processor id of one of its children). More...
 
void libmesh_assert_canonical_node_procids (const MeshBase &mesh)
 A function for verifying that processor assignment of nodes matches the heuristic specified in Node::choose_processor_id() More...
 
void libmesh_assert_valid_refinement_tree (const MeshBase &mesh)
 A function for verifying that elements on this processor have valid descendants and consistent active flags. More...
 
void libmesh_assert_no_links_to_elem (const MeshBase &mesh, const Elem *bad_elem)
 The following functions, only available in builds with DEBUG defined, typically have surprisingly slow asymptotic behavior, and so are unsuitable for use even with METHOD=devel. More...
 
void libmesh_assert_equal_points (const MeshBase &mesh)
 A function for testing that node locations match across processors. More...
 
void libmesh_assert_equal_connectivity (const MeshBase &mesh)
 A function for testing that element nodal connectivities match across processors. More...
 
void libmesh_assert_connected_nodes (const MeshBase &mesh)
 A function for verifying that all nodes are connected to at least one element. More...
 
void libmesh_assert_valid_constraint_rows (const MeshBase &mesh)
 A function for verifying that all mesh constraint rows express relations between nodes and elements that are semilocal (local or ghosted) to the current processor's portion of the mesh. More...
 
void libmesh_assert_valid_boundary_ids (const MeshBase &mesh)
 A function for verifying that boundary condition ids match across processors. More...
 
void libmesh_assert_valid_dof_ids (const MeshBase &mesh, unsigned int sysnum=libMesh::invalid_uint)
 A function for verifying that degree of freedom indexing matches across processors. More...
 
void libmesh_assert_valid_unique_ids (const MeshBase &mesh)
 A function for verifying that unique ids match across processors. More...
 
void libmesh_assert_consistent_distributed (const MeshBase &mesh)
 A function for verifying that distribution of dof objects is parallel consistent (every processor can see every node or element it owns) More...
 
void libmesh_assert_consistent_distributed_nodes (const MeshBase &mesh)
 A function for verifying that distribution of nodes is parallel consistent (every processor can see every node it owns) even before node ids have been made consistent. More...
 
void libmesh_assert_parallel_consistent_new_node_procids (const MeshBase &mesh)
 A function for verifying that processor assignment is parallel consistent (every processor agrees on the processor id of each node it can see) even on nodes which have not yet received consistent DofObject::id(), using element topology to identify matching nodes. More...
 
template<typename DofObjectSubclass >
void libmesh_assert_parallel_consistent_procids (const MeshBase &mesh)
 A function for verifying that processor assignment is parallel consistent (every processor agrees on the processor id of each dof object it can see) More...
 
template<typename DofObjectSubclass >
void libmesh_assert_valid_procids (const MeshBase &mesh)
 A function for verifying that processor assignment is both parallel and topologically consistent. More...
 
void libmesh_assert_valid_refinement_flags (const MeshBase &mesh)
 A function for verifying that refinement flags on elements are consistent between processors. More...
 
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 descendant of a neighbor of its neighbors) and consistent (each neighbor link goes to either the same neighbor or to a RemoteElem on each processor) More...
 

Detailed Description

Utility functions for operations on a Mesh object.

Here is where useful functions for interfacing with a Mesh should be defined. In general this namespace should be used to prevent the Mesh class from becoming too cluttered.

Author
Benjamin S. Kirk
Date
2004

Function Documentation

◆ bounding_sphere()

Sphere libMesh::MeshTools::bounding_sphere ( const MeshBase mesh)
Returns
A bounding sphere for mesh instead of a bounding box.

Definition at line 618 of file mesh_tools.C.

References create_bounding_box(), mesh, libMesh::TensorTools::norm(), and libMesh::Real.

619 {
621 
622  const Real diag = (bbox.second - bbox.first).norm();
623  const Point cent = (bbox.second + bbox.first)/2;
624 
625  return Sphere (cent, .5*diag);
626 }
This class defines a sphere.
Definition: sphere.h:72
libMesh::BoundingBox create_bounding_box(const MeshBase &mesh)
Definition: mesh_tools.C:566
MeshBase & mesh
Definition: mesh_tools.C:2393
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
auto norm(const T &a)
Definition: tensor_tools.h:74
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39

◆ build_nodes_to_elem_map() [1/4]

void libMesh::MeshTools::build_nodes_to_elem_map ( const MeshBase mesh,
std::vector< std::vector< dof_id_type >> &  nodes_to_elem_map 
)

After calling this function the input vector nodes_to_elem_map will contain the node to element connectivity.

That is to say nodes_to_elem_map[i][j] is the global number of \( j^{th} \) element connected to node i.

Definition at line 456 of file mesh_tools.C.

References libMesh::MeshBase::is_serial(), libMesh::MeshBase::max_node_id(), mesh, and libMesh::MeshBase::n_elem().

Referenced by libMesh::VariationalSmootherConstraint::constrain(), NodalNeighborsTest::do_test(), libMesh::GenericProjector< FFunctor, GFunctor, FValue, ProjectionAction >::GenericProjector(), libMesh::MeshTools::Subdivision::prepare_subdivision_mesh(), libMesh::C0Polyhedron::retriangulate(), libMesh::Partitioner::set_interface_node_processor_ids_BFS(), libMesh::Partitioner::set_interface_node_processor_ids_petscpartitioner(), MeshSmootherTest::testVariationalSmoother(), and libMesh::Tree< N >::Tree().

458 {
459  // A vector indexed over all nodes is too inefficient to use for a
460  // distributed mesh. Use the unordered_map API instead.
461  if (!mesh.is_serial())
462  libmesh_deprecated();
463 
464  nodes_to_elem_map.resize (mesh.max_node_id());
465 
466  for (const auto & elem : mesh.element_ptr_range())
467  for (auto & node : elem->node_ref_range())
468  {
469  libmesh_assert_less (node.id(), nodes_to_elem_map.size());
470  libmesh_assert_less (elem->id(), mesh.n_elem());
471 
472  nodes_to_elem_map[node.id()].push_back(elem->id());
473  }
474 }
MeshBase & mesh
Definition: mesh_tools.C:2393
virtual bool is_serial() const
Definition: mesh_base.h:347
virtual dof_id_type max_node_id() const =0
virtual dof_id_type n_elem() const =0

◆ build_nodes_to_elem_map() [2/4]

void libMesh::MeshTools::build_nodes_to_elem_map ( const MeshBase mesh,
std::vector< std::vector< const Elem *>> &  nodes_to_elem_map 
)

The same, except element pointers are returned instead of indices.

Definition at line 478 of file mesh_tools.C.

References libMesh::MeshBase::is_serial(), libMesh::MeshBase::max_node_id(), and mesh.

480 {
481  // A vector indexed over all nodes is too inefficient to use for a
482  // distributed mesh. Use the unordered_map API instead.
483  if (!mesh.is_serial())
484  libmesh_deprecated();
485 
486  nodes_to_elem_map.resize (mesh.max_node_id());
487 
488  for (const auto & elem : mesh.element_ptr_range())
489  for (auto & node : elem->node_ref_range())
490  {
491  libmesh_assert_less (node.id(), nodes_to_elem_map.size());
492 
493  nodes_to_elem_map[node.id()].push_back(elem);
494  }
495 }
MeshBase & mesh
Definition: mesh_tools.C:2393
virtual bool is_serial() const
Definition: mesh_base.h:347
virtual dof_id_type max_node_id() const =0

◆ build_nodes_to_elem_map() [3/4]

void libMesh::MeshTools::build_nodes_to_elem_map ( const MeshBase mesh,
std::unordered_map< dof_id_type, std::vector< dof_id_type >> &  nodes_to_elem_map 
)

After calling this function the input map nodes_to_elem_map will contain the node to element connectivity.

That is to say nodes_to_elem_map[i][j] is the global number of \( j^{th} \) element connected to node i.

Definition at line 499 of file mesh_tools.C.

References mesh.

501 {
502  nodes_to_elem_map.clear();
503 
504  for (const auto & elem : mesh.element_ptr_range())
505  for (auto & node : elem->node_ref_range())
506  nodes_to_elem_map[node.id()].push_back(elem->id());
507 }
MeshBase & mesh
Definition: mesh_tools.C:2393

◆ build_nodes_to_elem_map() [4/4]

void libMesh::MeshTools::build_nodes_to_elem_map ( const MeshBase mesh,
std::unordered_map< dof_id_type, std::vector< const Elem *>> &  nodes_to_elem_map 
)

The same, except element pointers are returned instead of indices.

Definition at line 511 of file mesh_tools.C.

References mesh.

513 {
514  nodes_to_elem_map.clear();
515 
516  for (const auto & elem : mesh.element_ptr_range())
517  for (auto & node : elem->node_ref_range())
518  nodes_to_elem_map[node.id()].push_back(elem);
519 }
MeshBase & mesh
Definition: mesh_tools.C:2393

◆ clear_spline_nodes()

void libMesh::MeshTools::clear_spline_nodes ( MeshBase mesh)

Remove spline node (for IsoGeometric Analysis meshes) elements and nodes and constraints from the mesh.

This should be done after the mesh is read but before the constraints are used by System initialization. The result is a mesh and solution space with lower required continuity and more unconstrained degrees of freedom, but with fewer total degrees of freedom and far fewer constraint equations.

Definition at line 1221 of file mesh_tools.C.

References libMesh::MeshBase::delete_elem(), libMesh::MeshBase::delete_node(), libMesh::MeshBase::get_constraint_rows(), libMesh::libmesh_assert(), libMesh::Elem::mapping_type(), mesh, libMesh::NODEELEM, libMesh::RATIONAL_BERNSTEIN_MAP, and libMesh::Elem::type().

Referenced by libMesh::DynaIO::read_mesh().

1222 {
1223  std::vector<Elem *> nodeelem_to_delete;
1224 
1225  for (auto & elem : mesh.element_ptr_range())
1226  if (elem->type() == NODEELEM &&
1227  elem->mapping_type() == RATIONAL_BERNSTEIN_MAP)
1228  nodeelem_to_delete.push_back(elem);
1229 
1230  auto & constraint_rows = mesh.get_constraint_rows();
1231 
1232  // All our constraint_rows ought to be for spline constraints we're
1233  // about to get rid of.
1234 #ifndef NDEBUG
1235  for (auto & node_row : constraint_rows)
1236  for (auto pr : node_row.second)
1237  {
1238  const Elem * elem = pr.first.first;
1239  libmesh_assert(elem->type() == NODEELEM);
1241  }
1242 #endif
1243 
1244  constraint_rows.clear();
1245 
1246  for (Elem * elem : nodeelem_to_delete)
1247  {
1248  Node * node = elem->node_ptr(0);
1249  mesh.delete_elem(elem);
1250  mesh.delete_node(node);
1251  }
1252 }
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1905
A Node is like a Point, but with more information.
Definition: node.h:52
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2393
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
ElemMappingType mapping_type() const
Definition: elem.h:3134
libmesh_assert(ctx)
virtual void delete_node(Node *n)=0
Removes the Node n from the mesh.
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2513
virtual ElemType type() const =0

◆ correct_node_proc_ids()

void libMesh::MeshTools::correct_node_proc_ids ( MeshBase mesh)

Changes the processor ids on each node so be the same as the id of the lowest element touching that node.

This corrects "orphaned" processor ids that may occur from element coarsening.

On a distributed mesh, this function must be called in parallel to sync everyone's corrected processor ids on ghost nodes.

Definition at line 2508 of file mesh_tools.C.

References libMesh::Node::choose_processor_id(), libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), libmesh_assert_parallel_consistent_procids< Node >(), mesh, n_elem(), new_proc_ids, libMesh::MeshBase::node_ref(), libMesh::ParallelObject::processor_id(), libMesh::MeshBase::skip_noncritical_partitioning(), and libMesh::Parallel::sync_dofobject_data_by_id().

Referenced by libMesh::MeshCommunication::make_new_nodes_parallel_consistent(), libMesh::MeshCommunication::make_nodes_parallel_consistent(), and libMesh::MeshBase::partition().

2509 {
2510  LOG_SCOPE("correct_node_proc_ids()","MeshTools");
2511 
2512  // This function must be run on all processors at once
2513  libmesh_parallel_only(mesh.comm());
2514 
2515  // We require all processors to agree on nodal processor ids before
2516  // going into this algorithm.
2517 #ifdef DEBUG
2519 #endif
2520 
2521  // If we have any unpartitioned elements at this
2522  // stage there is a problem
2523  libmesh_assert (n_elem(mesh.unpartitioned_elements_begin(),
2524  mesh.unpartitioned_elements_end()) == 0);
2525 
2526  // Fix nodes' processor ids. Coarsening may have left us with nodes
2527  // which are no longer touched by any elements of the same processor
2528  // id, and for DofMap to work we need to fix that.
2529 
2530  // This is harder now that libMesh no longer requires a distributed
2531  // mesh to ghost all nodal neighbors: it is possible for two active
2532  // elements on two different processors to share the same node in
2533  // such a way that neither processor knows the others' element
2534  // exists!
2535 
2536  // While we're at it, if this mesh is configured to allow
2537  // repartitioning, we'll repartition *all* the nodes' processor ids
2538  // using the canonical Node heuristic, to try and improve DoF load
2539  // balancing. But if the mesh is disallowing repartitioning, we
2540  // won't touch processor_id on any node where it's valid, regardless
2541  // of whether or not it's canonical.
2542  bool repartition_all_nodes = !mesh.skip_noncritical_partitioning();
2543  std::unordered_set<const Node *> valid_nodes;
2544 
2545  // If we aren't allowed to repartition, then we're going to leave
2546  // every node we can at its current processor_id, and *only*
2547  // repartition the nodes whose current processor id is incompatible
2548  // with DoFMap (because it doesn't touch an active element, e.g. due
2549  // to coarsening)
2550  if (!repartition_all_nodes)
2551  {
2552  for (const auto & elem : mesh.active_element_ptr_range())
2553  for (const auto & node : elem->node_ref_range())
2554  if (elem->processor_id() == node.processor_id())
2555  valid_nodes.insert(&node);
2556 
2557  SyncNodeSet syncv(valid_nodes, mesh);
2558 
2560  (mesh.comm(), mesh.nodes_begin(), mesh.nodes_end(), syncv);
2561  }
2562 
2563  // We build up a set of compatible processor ids for each node
2564  proc_id_map_type new_proc_ids;
2565 
2566  for (auto & elem : mesh.active_element_ptr_range())
2567  {
2568  processor_id_type pid = elem->processor_id();
2569 
2570  for (auto & node : elem->node_ref_range())
2571  {
2572  const dof_id_type id = node.id();
2573  if (auto it = new_proc_ids.find(id);
2574  it == new_proc_ids.end())
2575  new_proc_ids.emplace(id, pid);
2576  else
2577  it->second = node.choose_processor_id(it->second, pid);
2578  }
2579  }
2580 
2581  // Sort the new pids to push to each processor
2582  std::map<processor_id_type, std::vector<std::pair<dof_id_type, processor_id_type>>>
2583  ids_to_push;
2584 
2585  for (const auto & node : mesh.node_ptr_range())
2586  if (const auto it = std::as_const(new_proc_ids).find(node->id());
2587  it != new_proc_ids.end() && node->processor_id() != DofObject::invalid_processor_id)
2588  ids_to_push[node->processor_id()].emplace_back(node->id(), /*pid=*/it->second);
2589 
2590  auto action_functor =
2591  [& mesh, & new_proc_ids]
2593  const std::vector<std::pair<dof_id_type, processor_id_type>> & data)
2594  {
2595  for (const auto & [id, pid] : data)
2596  {
2597  if (const auto it = new_proc_ids.find(id);
2598  it == new_proc_ids.end())
2599  new_proc_ids.emplace(id, pid);
2600  else
2601  {
2602  const Node & node = mesh.node_ref(id);
2603  it->second = node.choose_processor_id(it->second, pid);
2604  }
2605  }
2606  };
2607 
2608  Parallel::push_parallel_vector_data
2609  (mesh.comm(), ids_to_push, action_functor);
2610 
2611  // Now new_proc_ids is correct for every node we used to own. Let's
2612  // ask every other processor about the nodes they used to own. But
2613  // first we'll need to keep track of which nodes we used to own,
2614  // lest we get them confused with nodes we newly own.
2615  std::unordered_set<Node *> ex_local_nodes;
2616  for (auto & node : mesh.local_node_ptr_range())
2617  if (const auto it = new_proc_ids.find(node->id());
2618  it != new_proc_ids.end() && it->second != mesh.processor_id())
2619  ex_local_nodes.insert(node);
2620 
2621  SyncProcIdsFromMap sync(new_proc_ids, mesh);
2622  if (repartition_all_nodes)
2624  (mesh.comm(), mesh.nodes_begin(), mesh.nodes_end(), sync);
2625  else
2626  {
2627  NodesNotInSet nnis(valid_nodes);
2628 
2630  (mesh.comm(), mesh.nodes_begin(), mesh.nodes_end(), nnis, sync);
2631  }
2632 
2633  // And finally let's update the nodes we used to own.
2634  for (const auto & node : ex_local_nodes)
2635  {
2636  if (valid_nodes.count(node))
2637  continue;
2638 
2639  const dof_id_type id = node->id();
2640  const proc_id_map_type::iterator it = new_proc_ids.find(id);
2641  libmesh_assert(it != new_proc_ids.end());
2642  node->processor_id() = it->second;
2643  }
2644 
2645  // We should still have consistent nodal processor ids coming out of
2646  // this algorithm, but if we're allowed to repartition the mesh then
2647  // they should be canonically correct too.
2648 #ifdef DEBUG
2649  libmesh_assert_valid_procids<Node>(mesh);
2650  //if (repartition_all_nodes)
2651  // libmesh_assert_canonical_node_procids(mesh);
2652 #endif
2653 }
A Node is like a Point, but with more information.
Definition: node.h:52
dof_id_type n_elem(const MeshBase::const_element_iterator &begin, const MeshBase::const_element_iterator &end)
Count up the number of elements of a specific type (as defined by an iterator range).
Definition: mesh_tools.C:1004
void skip_noncritical_partitioning(bool skip)
If true is passed in then the elements on this mesh will no longer be (re)partitioned, and the nodes on this mesh will only be repartitioned if they are found "orphaned" via coarsening or other removal of the last element responsible for their node/element processor id consistency.
Definition: mesh_base.h:1401
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
processor_id_type choose_processor_id(processor_id_type pid1, processor_id_type pid2) const
Return which of pid1 and pid2 would be preferred by the current load-balancing heuristic applied to t...
Definition: node.C:78
uint8_t processor_id_type
libmesh_assert(ctx)
const proc_id_map_type & new_proc_ids
Definition: mesh_tools.C:2463
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost dofobjects uniquely identified by their id.
void libmesh_assert_parallel_consistent_procids< Node >(const MeshBase &mesh)
Definition: mesh_tools.C:2218
virtual const Node & node_ref(const dof_id_type i) const
Definition: mesh_base.h:735
processor_id_type processor_id() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ create_bounding_box()

libMesh::BoundingBox libMesh::MeshTools::create_bounding_box ( const MeshBase mesh)
Returns
A BoundingBox that bounds the mesh.

Definition at line 566 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), create_local_bounding_box(), libMesh::DofObject::invalid_processor_id, TIMPI::Communicator::max(), mesh, TIMPI::Communicator::min(), and libMesh::Threads::parallel_reduce().

Referenced by libMesh::Partitioner::_find_global_index_by_pid_map(), bounding_sphere(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::MeshTetInterface::check_hull_integrity(), libMesh::MeshBase::get_info(), libMesh::PointLocatorTree::init(), libMesh::ParmetisPartitioner::initialize(), libMesh::MetisPartitioner::partition_range(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::TreeNode< N >::refine(), MeshGenerationTest::testBuildCube(), MeshGenerationTest::testBuildLine(), MeshGenerationTest::testBuildSquare(), libMesh::Tree< N >::Tree(), and libMesh::PostscriptIO::write().

567 {
568  // This function must be run on all processors at once
569  libmesh_parallel_only(mesh.comm());
570 
571  FindBBox find_bbox;
572 
573  // Start with any unpartitioned elements we know about locally
574  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(DofObject::invalid_processor_id),
575  mesh.pid_elements_end(DofObject::invalid_processor_id)),
576  find_bbox);
577 
578  // And combine with our local elements
579  find_bbox.bbox().union_with(create_local_bounding_box(mesh));
580 
581  // Compare the bounding boxes across processors
582  mesh.comm().min(find_bbox.min());
583  mesh.comm().max(find_bbox.max());
584 
585  return find_bbox.bbox();
586 }
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2393
libMesh::BoundingBox create_local_bounding_box(const MeshBase &mesh)
Definition: mesh_tools.C:631
void min(const T &r, T &o, Request &req) const
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:109
void max(const T &r, T &o, Request &req) const

◆ create_local_bounding_box()

libMesh::BoundingBox libMesh::MeshTools::create_local_bounding_box ( const MeshBase mesh)
Returns
Two points defining a cartesian box that bounds the elements belonging to the local processor.

Unlike the other bounding box creation functions, this does not need to be run in parallel, because this is the only function we can guarantee can be resolved with only local information.

Definition at line 631 of file mesh_tools.C.

References mesh, and libMesh::Threads::parallel_reduce().

Referenced by create_bounding_box(), and libMesh::MeshBase::get_info().

632 {
633  FindBBox find_bbox;
634 
635  Threads::parallel_reduce (ConstElemRange (mesh.local_elements_begin(),
636  mesh.local_elements_end()),
637  find_bbox);
638 
639  return find_bbox.bbox();
640 }
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2393
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:109

◆ create_nodal_bounding_box()

libMesh::BoundingBox libMesh::MeshTools::create_nodal_bounding_box ( const MeshBase mesh)
Returns
Two points defining a cartesian box that bounds the nodes of the mesh.

In the case of curved elements, this box might not bound the elements of the mesh.

Definition at line 591 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, TIMPI::Communicator::max(), mesh, TIMPI::Communicator::min(), and libMesh::Threads::parallel_reduce().

Referenced by libMesh::MeshCommunication::assign_global_indices(), and libMesh::MeshCommunication::check_for_duplicate_global_indices().

592 {
593  // This function must be run on all processors at once
594  libmesh_parallel_only(mesh.comm());
595 
596  FindBBox find_bbox;
597 
598  // Start with any unpartitioned nodes we know about locally
599  Threads::parallel_reduce (ConstNodeRange (mesh.pid_nodes_begin(DofObject::invalid_processor_id),
600  mesh.pid_nodes_end(DofObject::invalid_processor_id)),
601  find_bbox);
602 
603  // Add our local nodes
604  Threads::parallel_reduce (ConstNodeRange (mesh.local_nodes_begin(),
605  mesh.local_nodes_end()),
606  find_bbox);
607 
608  // Compare the bounding boxes across processors
609  mesh.comm().min(find_bbox.min());
610  mesh.comm().max(find_bbox.max());
611 
612  return find_bbox.bbox();
613 }
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2393
void min(const T &r, T &o, Request &req) const
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:109
void max(const T &r, T &o, Request &req) const

◆ create_processor_bounding_box()

libMesh::BoundingBox libMesh::MeshTools::create_processor_bounding_box ( const MeshBase mesh,
const processor_id_type  pid 
)
Returns
A BoundingBox that bounds the elements belonging to processor pid.

Definition at line 645 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), mesh, TIMPI::Communicator::min(), libMesh::ParallelObject::n_processors(), libMesh::Threads::parallel_reduce(), and TIMPI::Communicator::verify().

Referenced by processor_bounding_sphere().

647 {
648  // This can only be run in parallel, with consistent arguments.
649  libmesh_parallel_only(mesh.comm());
650  libmesh_assert(mesh.comm().verify(pid));
651 
652  libmesh_assert_less (pid, mesh.n_processors());
653 
654  FindBBox find_bbox;
655 
656  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
657  mesh.pid_elements_end(pid)),
658  find_bbox);
659 
660  // Compare the bounding boxes across processors
661  mesh.comm().min(find_bbox.min());
662  mesh.comm().max(find_bbox.max());
663 
664  return find_bbox.bbox();
665 }
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2393
processor_id_type n_processors() const
void min(const T &r, T &o, Request &req) const
libmesh_assert(ctx)
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:109
timpi_pure bool verify(const T &r) const
void max(const T &r, T &o, Request &req) const

◆ create_subdomain_bounding_box()

libMesh::BoundingBox libMesh::MeshTools::create_subdomain_bounding_box ( const MeshBase mesh,
const subdomain_id_type  sid 
)
Returns
A BoundingBox that bounds the elements belonging to subdomain sid.

Definition at line 685 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), mesh, TIMPI::Communicator::min(), libMesh::Threads::parallel_reduce(), and TIMPI::Communicator::verify().

Referenced by subdomain_bounding_sphere().

687 {
688  // This can only be run in parallel, with consistent arguments.
689  libmesh_parallel_only(mesh.comm());
690  libmesh_assert(mesh.comm().verify(sid));
691 
692  FindBBox find_bbox;
693 
695  (ConstElemRange (mesh.active_local_subdomain_elements_begin(sid),
696  mesh.active_local_subdomain_elements_end(sid)),
697  find_bbox);
698 
699  // Compare the bounding boxes across processors
700  mesh.comm().min(find_bbox.min());
701  mesh.comm().max(find_bbox.max());
702 
703  return find_bbox.bbox();
704 }
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2393
void min(const T &r, T &o, Request &req) const
libmesh_assert(ctx)
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:109
timpi_pure bool verify(const T &r) const
void max(const T &r, T &o, Request &req) const

◆ elem_types()

void libMesh::MeshTools::elem_types ( const MeshBase mesh,
std::vector< ElemType > &  et 
)

Fills in a vector of all element types in the mesh.

Implemented in terms of element_iterators.

Definition at line 723 of file mesh_tools.C.

References mesh.

Referenced by libMesh::MeshBase::get_info().

725 {
726  // Loop over the the elements. If the current element type isn't in
727  // the vector, insert it.
728  for (const auto & elem : mesh.element_ptr_range())
729  if (!std::count(et.begin(), et.end(), elem->type()))
730  et.push_back(elem->type());
731 }
MeshBase & mesh
Definition: mesh_tools.C:2393

◆ find_block_boundary_nodes()

std::unordered_set< dof_id_type > libMesh::MeshTools::find_block_boundary_nodes ( const MeshBase mesh)

Returns a std::set containing Node IDs for all of the block boundary nodes.

A "block boundary node" is a node that is connected to elements from 2 or more blocks

Definition at line 544 of file mesh_tools.C.

References mesh.

Referenced by libMesh::LaplaceMeshSmoother::smooth().

545 {
546  std::unordered_set<dof_id_type> block_boundary_nodes;
547 
548  // Loop over elements, find those on boundary, and
549  // mark them as true in on_boundary.
550  for (const auto & elem : mesh.active_element_ptr_range())
551  for (auto s : elem->side_index_range())
552  if (elem->neighbor_ptr(s) && (elem->neighbor_ptr(s)->subdomain_id() != elem->subdomain_id()))
553  {
554  auto nodes_on_side = elem->nodes_on_side(s);
555 
556  for (auto & local_id : nodes_on_side)
557  block_boundary_nodes.insert(elem->node_ptr(local_id)->id());
558  }
559 
560  return block_boundary_nodes;
561 }
MeshBase & mesh
Definition: mesh_tools.C:2393

◆ find_boundary_nodes()

std::unordered_set< dof_id_type > libMesh::MeshTools::find_boundary_nodes ( const MeshBase mesh)

Calling this function on a 2D mesh will convert all the elements to triangles.

QUAD4s will be converted to TRI3s, QUAD8s and QUAD9s will be converted to TRI6s. Returns a std::set containing Node IDs for all of the boundary nodes

Definition at line 524 of file mesh_tools.C.

References mesh.

Referenced by libMesh::VariationalSmootherConstraint::constrain(), libMesh::MeshTools::Modification::distort(), DistortTest::perturb_and_check(), libMesh::LaplaceMeshSmoother::smooth(), and libMesh::MeshTools::Modification::smooth().

525 {
526  std::unordered_set<dof_id_type> boundary_nodes;
527 
528  // Loop over elements, find those on boundary, and
529  // mark them as true in on_boundary.
530  for (const auto & elem : mesh.active_element_ptr_range())
531  for (auto s : elem->side_index_range())
532  if (elem->neighbor_ptr(s) == nullptr) // on the boundary
533  {
534  auto nodes_on_side = elem->nodes_on_side(s);
535 
536  for (auto & local_id : nodes_on_side)
537  boundary_nodes.insert(elem->node_ptr(local_id)->id());
538  }
539 
540  return boundary_nodes;
541 }
MeshBase & mesh
Definition: mesh_tools.C:2393

◆ find_hanging_nodes_and_parents()

void libMesh::MeshTools::find_hanging_nodes_and_parents ( const MeshBase mesh,
std::map< dof_id_type, std::vector< dof_id_type >> &  hanging_nodes 
)

Given a mesh hanging_nodes will be filled with an associative array keyed off the global id of all the hanging nodes in the mesh.

It will hold an array of the parents of the node (meaning the two nodes to either side of it that make up the side the hanging node is on.

Definition at line 1133 of file mesh_tools.C.

References libMesh::Elem::is_node_on_side(), libMesh::Elem::level(), mesh, libMesh::Elem::n_neighbors(), libMesh::Elem::n_sides(), libMesh::Elem::neighbor_ptr(), libMesh::Elem::node_id(), libMesh::Elem::parent(), libMesh::QUAD4, and libMesh::Elem::which_neighbor_am_i().

1135 {
1136  // Loop through all the elements
1137  for (auto & elem : mesh.active_local_element_ptr_range())
1138  if (elem->type() == QUAD4)
1139  for (auto s : elem->side_index_range())
1140  {
1141  // Loop over the sides looking for sides that have hanging nodes
1142  // This code is inspired by compute_proj_constraints()
1143  const Elem * neigh = elem->neighbor_ptr(s);
1144 
1145  // If not a boundary side
1146  if (neigh != nullptr)
1147  {
1148  // Is there a coarser element next to this one?
1149  if (neigh->level() < elem->level())
1150  {
1151  const Elem * ancestor = elem;
1152  while (neigh->level() < ancestor->level())
1153  ancestor = ancestor->parent();
1154  unsigned int s_neigh = neigh->which_neighbor_am_i(ancestor);
1155  libmesh_assert_less (s_neigh, neigh->n_neighbors());
1156 
1157  // Couple of helper uints...
1158  unsigned int local_node1=0;
1159  unsigned int local_node2=0;
1160 
1161  bool found_in_neighbor = false;
1162 
1163  // Find the two vertices that make up this side
1164  while (!elem->is_node_on_side(local_node1++,s)) { }
1165  local_node1--;
1166 
1167  // Start looking for the second one with the next node
1168  local_node2=local_node1+1;
1169 
1170  // Find the other one
1171  while (!elem->is_node_on_side(local_node2++,s)) { }
1172  local_node2--;
1173 
1174  //Pull out their global ids:
1175  dof_id_type node1 = elem->node_id(local_node1);
1176  dof_id_type node2 = elem->node_id(local_node2);
1177 
1178  // Now find which node is present in the neighbor
1179  // FIXME This assumes a level one rule!
1180  // The _other_ one is the hanging node
1181 
1182  // First look for the first one
1183  // FIXME could be streamlined a bit
1184  for (unsigned int n=0;n<neigh->n_sides();n++)
1185  if (neigh->node_id(n) == node1)
1186  found_in_neighbor=true;
1187 
1188  dof_id_type hanging_node=0;
1189 
1190  if (!found_in_neighbor)
1191  hanging_node=node1;
1192  else // If it wasn't node1 then it must be node2!
1193  hanging_node=node2;
1194 
1195  // Reset for reuse
1196  local_node1=0;
1197 
1198  // Find the first node that makes up the side in the neighbor (these should be the parent nodes)
1199  while (!neigh->is_node_on_side(local_node1++,s_neigh)) { }
1200  local_node1--;
1201 
1202  local_node2=local_node1+1;
1203 
1204  // Find the second node...
1205  while (!neigh->is_node_on_side(local_node2++,s_neigh)) { }
1206  local_node2--;
1207 
1208  // Save them if we haven't already found the parents for this one
1209  if (hanging_nodes[hanging_node].size()<2)
1210  {
1211  hanging_nodes[hanging_node].push_back(neigh->node_id(local_node1));
1212  hanging_nodes[hanging_node].push_back(neigh->node_id(local_node2));
1213  }
1214  }
1215  }
1216  }
1217 }
const Elem * parent() const
Definition: elem.h:3044
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
MeshBase & mesh
Definition: mesh_tools.C:2393
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition: elem.h:2933
virtual unsigned int n_sides() const =0
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2612
unsigned int level() const
Definition: elem.h:3088
unsigned int n_neighbors() const
Definition: elem.h:713
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2481
uint8_t dof_id_type
Definition: id_types.h:67

◆ find_nodal_neighbors() [1/2]

void libMesh::MeshTools::find_nodal_neighbors ( const MeshBase mesh,
const Node n,
const std::vector< std::vector< const Elem *>> &  nodes_to_elem_map,
std::vector< const Node *> &  neighbors 
)

Given a mesh and a node in the mesh, the vector will be filled with every node directly attached to the given one.

Definition at line 1071 of file mesh_tools.C.

References libMesh::DofObject::id().

Referenced by NodalNeighborsTest::do_test(), find_nodal_or_face_neighbors(), libMesh::MeshTools::Subdivision::prepare_subdivision_mesh(), libMesh::Partitioner::set_interface_node_processor_ids_BFS(), and libMesh::Partitioner::set_interface_node_processor_ids_petscpartitioner().

1075 {
1076  find_nodal_neighbors_helper(node.id(), nodes_to_elem_map[node.id()],
1077  neighbors);
1078 }

◆ find_nodal_neighbors() [2/2]

void libMesh::MeshTools::find_nodal_neighbors ( const MeshBase mesh,
const Node n,
const std::unordered_map< dof_id_type, std::vector< const Elem *>> &  nodes_to_elem_map,
std::vector< const Node *> &  neighbors 
)

Given a mesh and a node in the mesh, the vector will be filled with every node directly attached to the given one.

Definition at line 1082 of file mesh_tools.C.

References libMesh::DofObject::id().

1086 {
1087  const std::vector<const Elem *> node_to_elem_vec =
1088  libmesh_map_find(nodes_to_elem_map, node.id());
1089  find_nodal_neighbors_helper(node.id(), node_to_elem_vec, neighbors);
1090 }

◆ find_nodal_or_face_neighbors()

void libMesh::MeshTools::find_nodal_or_face_neighbors ( const MeshBase mesh,
const Node node,
const std::unordered_map< dof_id_type, std::vector< const Elem *>> &  nodes_to_elem_map,
std::vector< const Node *> &  neighbors 
)

Given a mesh and a node in the mesh, the vector will be filled with every node directly attached to the given one.

IF NO nodal neighbors are found, all nodes on the containing side are treated as neighbors. This is useful when the node does not lie on an edge, such as the central face node in HEX27, TET14, etc. elements.

Definition at line 1092 of file mesh_tools.C.

References find_nodal_neighbors(), libMesh::DofObject::id(), libMesh::libmesh_assert(), and mesh.

Referenced by libMesh::VariationalSmootherConstraint::get_neighbors_for_boundary_constraint(), libMesh::VariationalSmootherConstraint::get_neighbors_for_subdomain_constraint(), and MeshSmootherTest::testVariationalSmoother().

1097 {
1098  // Find all the nodal neighbors... that is the nodes directly connected
1099  // to this node through one edge.
1100  find_nodal_neighbors(mesh, node, nodes_to_elem_map, neighbors);
1101 
1102  // If no neighbors are found, use all nodes on the containing side as
1103  // neighbors.
1104  if (!neighbors.size())
1105  {
1106  // Grab the element containing node
1107  const auto * elem = libmesh_map_find(nodes_to_elem_map, node.id()).front();
1108  // Find the element side containing node
1109  for (const auto &side : elem->side_index_range())
1110  {
1111  const auto &nodes_on_side = elem->nodes_on_side(side);
1112  const auto it =
1113  std::find_if(nodes_on_side.begin(), nodes_on_side.end(), [&](auto local_node_id) {
1114  return elem->node_id(local_node_id) == node.id();
1115  });
1116 
1117  if (it != nodes_on_side.end())
1118  {
1119  for (const auto &local_node_id : nodes_on_side)
1120  // No need to add node itself as a neighbor
1121  if (const auto *node_ptr = elem->node_ptr(local_node_id);
1122  *node_ptr != node)
1123  neighbors.push_back(node_ptr);
1124  break;
1125  }
1126  }
1127  }
1128  libmesh_assert(neighbors.size());
1129 }
void find_nodal_neighbors(const MeshBase &mesh, const Node &n, const std::vector< std::vector< const Elem *>> &nodes_to_elem_map, std::vector< const Node *> &neighbors)
Given a mesh and a node in the mesh, the vector will be filled with every node directly attached to t...
Definition: mesh_tools.C:1071
MeshBase & mesh
Definition: mesh_tools.C:2393
dof_id_type id() const
Definition: dof_object.h:819
libmesh_assert(ctx)

◆ get_not_subactive_node_ids()

void libMesh::MeshTools::get_not_subactive_node_ids ( const MeshBase mesh,
std::set< dof_id_type > &  not_subactive_node_ids 
)

Builds a set of node IDs for nodes which belong to non-subactive elements.

Non-subactive elements are those which are either active or inactive. This is useful for determining which nodes should be written to a data file, and is used by the XDA mesh writing methods.

Definition at line 993 of file mesh_tools.C.

References mesh.

995 {
996  for (const auto & elem : mesh.element_ptr_range())
997  if (!elem->subactive())
998  for (auto & n : elem->node_ref_range())
999  not_subactive_node_ids.insert(n.id());
1000 }
MeshBase & mesh
Definition: mesh_tools.C:2393

◆ libmesh_assert_canonical_node_procids()

void libMesh::MeshTools::libmesh_assert_canonical_node_procids ( const MeshBase mesh)

A function for verifying that processor assignment of nodes matches the heuristic specified in Node::choose_processor_id()

Definition at line 1614 of file mesh_tools.C.

References mesh.

1615 {
1616  for (const auto & elem : mesh.active_element_ptr_range())
1617  for (auto & node : elem->node_ref_range())
1618  libmesh_assert_equal_to
1619  (node.processor_id(),
1620  node.choose_processor_id(node.processor_id(),
1621  elem->processor_id()));
1622 }
MeshBase & mesh
Definition: mesh_tools.C:2393

◆ libmesh_assert_connected_nodes()

void libMesh::MeshTools::libmesh_assert_connected_nodes ( const MeshBase mesh)

A function for verifying that all nodes are connected to at least one element.

This will fail in the most general case. When DistributedMesh and NodeConstraints are enabled, we expect the possibility that a processor will be given remote nodes to satisfy node constraints without also being given the remote elements connected to those nodes.

Definition at line 1722 of file mesh_tools.C.

References libMesh::libmesh_assert(), and mesh.

1723 {
1724  LOG_SCOPE("libmesh_assert_connected_nodes()", "MeshTools");
1725 
1726  std::set<const Node *> used_nodes;
1727 
1728  for (const auto & elem : mesh.element_ptr_range())
1729  {
1730  libmesh_assert (elem);
1731 
1732  for (auto & n : elem->node_ref_range())
1733  used_nodes.insert(&n);
1734  }
1735 
1736  for (const auto & node : mesh.node_ptr_range())
1737  {
1738  libmesh_assert(node);
1739  libmesh_assert(used_nodes.count(node));
1740  }
1741 }
MeshBase & mesh
Definition: mesh_tools.C:2393
libmesh_assert(ctx)

◆ libmesh_assert_consistent_distributed()

void libMesh::MeshTools::libmesh_assert_consistent_distributed ( const MeshBase mesh)

A function for verifying that distribution of dof objects is parallel consistent (every processor can see every node or element it owns)

Definition at line 2069 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::max_node_id(), mesh, TIMPI::Communicator::min(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::MeshBase::query_elem_ptr(), and libMesh::MeshBase::query_node_ptr().

2070 {
2071  libmesh_parallel_only(mesh.comm());
2072 
2073  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
2074  mesh.comm().max(parallel_max_elem_id);
2075 
2076  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2077  {
2078  const Elem * elem = mesh.query_elem_ptr(i);
2079  processor_id_type pid =
2080  elem ? elem->processor_id() : DofObject::invalid_processor_id;
2081  mesh.comm().min(pid);
2082  libmesh_assert(elem || pid != mesh.processor_id());
2083  }
2084 
2085  dof_id_type parallel_max_node_id = mesh.max_node_id();
2086  mesh.comm().max(parallel_max_node_id);
2087 
2088  for (dof_id_type i=0; i != parallel_max_node_id; ++i)
2089  {
2090  const Node * node = mesh.query_node_ptr(i);
2091  processor_id_type pid =
2092  node ? node->processor_id() : DofObject::invalid_processor_id;
2093  mesh.comm().min(pid);
2094  libmesh_assert(node || pid != mesh.processor_id());
2095  }
2096 }
A Node is like a Point, but with more information.
Definition: node.h:52
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
uint8_t processor_id_type
void min(const T &r, T &o, Request &req) const
virtual const Node * query_node_ptr(const dof_id_type i) const =0
virtual dof_id_type max_elem_id() const =0
libmesh_assert(ctx)
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
virtual dof_id_type max_node_id() const =0
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:881
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_consistent_distributed_nodes()

void libMesh::MeshTools::libmesh_assert_consistent_distributed_nodes ( const MeshBase mesh)

A function for verifying that distribution of nodes is parallel consistent (every processor can see every node it owns) even before node ids have been made consistent.

Definition at line 2099 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), mesh, TIMPI::Communicator::min(), n_nodes(), libMesh::Elem::n_nodes(), libMesh::Elem::node_ptr(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::MeshBase::query_elem_ptr(), TIMPI::Communicator::semiverify(), and libMesh::MeshBase::sub_point_locator().

2100 {
2101  libmesh_parallel_only(mesh.comm());
2102  auto locator = mesh.sub_point_locator();
2103 
2104  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
2105  mesh.comm().max(parallel_max_elem_id);
2106 
2107  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2108  {
2109  const Elem * elem = mesh.query_elem_ptr(i);
2110 
2111  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
2112  unsigned int n_nodes = my_n_nodes;
2113  mesh.comm().max(n_nodes);
2114 
2115  if (n_nodes)
2116  libmesh_assert(mesh.comm().semiverify(elem ? &my_n_nodes : nullptr));
2117 
2118  for (unsigned int n=0; n != n_nodes; ++n)
2119  {
2120  const Node * node = elem ? elem->node_ptr(n) : nullptr;
2121  processor_id_type pid =
2122  node ? node->processor_id() : DofObject::invalid_processor_id;
2123  mesh.comm().min(pid);
2124  libmesh_assert(node || pid != mesh.processor_id());
2125  }
2126  }
2127 }
A Node is like a Point, but with more information.
Definition: node.h:52
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:1826
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
uint8_t processor_id_type
const dof_id_type n_nodes
Definition: tecplot_io.C:67
void min(const T &r, T &o, Request &req) const
virtual unsigned int n_nodes() const =0
virtual dof_id_type max_elem_id() const =0
libmesh_assert(ctx)
timpi_pure bool semiverify(const T *r) const
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2513
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:881
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_contiguous_dof_ids()

void libMesh::MeshTools::libmesh_assert_contiguous_dof_ids ( const MeshBase mesh,
unsigned int  sysnum 
)

A function for verifying that degree of freedom indexes are contiguous on each processor, as is required by libMesh numeric classes.

Verify a particular system by specifying that system's number.

Definition at line 1477 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::make_range(), mesh, libMesh::ParallelObject::n_processors(), and libMesh::ParallelObject::processor_id().

1478 {
1479  LOG_SCOPE("libmesh_assert_contiguous_dof_ids()", "MeshTools");
1480 
1481  if (mesh.n_processors() == 1)
1482  return;
1483 
1484  libmesh_parallel_only(mesh.comm());
1485 
1486  dof_id_type min_dof_id = std::numeric_limits<dof_id_type>::max(),
1487  max_dof_id = std::numeric_limits<dof_id_type>::min();
1488 
1489  // Figure out what our local dof id range is
1490  for (const auto * node : mesh.local_node_ptr_range())
1491  {
1492  for (auto v : make_range(node->n_vars(sysnum)))
1493  for (auto c : make_range(node->n_comp(sysnum, v)))
1494  {
1495  dof_id_type id = node->dof_number(sysnum, v, c);
1496  min_dof_id = std::min (min_dof_id, id);
1497  max_dof_id = std::max (max_dof_id, id);
1498  }
1499  }
1500 
1501  // Make sure no other processors' ids are inside it
1502  for (const auto * node : mesh.node_ptr_range())
1503  {
1504  if (node->processor_id() == mesh.processor_id())
1505  continue;
1506  for (auto v : make_range(node->n_vars(sysnum)))
1507  for (auto c : make_range(node->n_comp(sysnum, v)))
1508  {
1509  dof_id_type id = node->dof_number(sysnum, v, c);
1510  libmesh_assert (id < min_dof_id ||
1511  id > max_dof_id);
1512  }
1513  }
1514 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
processor_id_type n_processors() const
libmesh_assert(ctx)
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:176
processor_id_type processor_id() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_equal_connectivity()

void libMesh::MeshTools::libmesh_assert_equal_connectivity ( const MeshBase mesh)

A function for testing that element nodal connectivities match across processors.

Definition at line 1701 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), mesh, libMesh::Elem::node_id(), libMesh::Elem::node_index_range(), libMesh::MeshBase::query_elem_ptr(), and TIMPI::Communicator::semiverify().

Referenced by libMesh::MeshCommunication::assign_global_indices(), and libMesh::SimplexRefiner::refine_via_edges().

1702 {
1703  LOG_SCOPE("libmesh_assert_equal_connectivity()", "MeshTools");
1704 
1705  dof_id_type pmax_elem_id = mesh.max_elem_id();
1706  mesh.comm().max(pmax_elem_id);
1707 
1708  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1709  {
1710  const Elem * e = mesh.query_elem_ptr(i);
1711 
1712  std::vector<dof_id_type> nodes;
1713  if (e)
1714  for (auto n : e->node_index_range())
1715  nodes.push_back(e->node_id(n));
1716 
1717  libmesh_assert(mesh.comm().semiverify(e ? &nodes : nullptr));
1718  }
1719 }
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
virtual dof_id_type max_elem_id() const =0
libmesh_assert(ctx)
timpi_pure bool semiverify(const T *r) const
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
IntRange< unsigned short > node_index_range() const
Definition: elem.h:2697
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2481
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_equal_n_systems()

void libMesh::MeshTools::libmesh_assert_equal_n_systems ( const MeshBase mesh)

The following functions, only available in builds with NDEBUG undefined, are for asserting internal consistency that we hope should never be broken in opt.

A function for testing that all DofObjects within a mesh have the same n_systems count

Definition at line 1292 of file mesh_tools.C.

References libMesh::invalid_uint, and mesh.

1293 {
1294  LOG_SCOPE("libmesh_assert_equal_n_systems()", "MeshTools");
1295 
1296  unsigned int n_sys = libMesh::invalid_uint;
1297 
1298  for (const auto & elem : mesh.element_ptr_range())
1299  {
1300  if (n_sys == libMesh::invalid_uint)
1301  n_sys = elem->n_systems();
1302  else
1303  libmesh_assert_equal_to (elem->n_systems(), n_sys);
1304  }
1305 
1306  for (const auto & node : mesh.node_ptr_range())
1307  {
1308  if (n_sys == libMesh::invalid_uint)
1309  n_sys = node->n_systems();
1310  else
1311  libmesh_assert_equal_to (node->n_systems(), n_sys);
1312  }
1313 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:303
MeshBase & mesh
Definition: mesh_tools.C:2393

◆ libmesh_assert_equal_points()

void libMesh::MeshTools::libmesh_assert_equal_points ( const MeshBase mesh)

A function for testing that node locations match across processors.

Definition at line 1685 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_node_id(), mesh, libMesh::MeshBase::query_node_ptr(), and TIMPI::Communicator::semiverify().

Referenced by libMesh::MeshCommunication::assign_global_indices(), and libMesh::SimplexRefiner::refine_via_edges().

1686 {
1687  LOG_SCOPE("libmesh_assert_equal_points()", "MeshTools");
1688 
1689  dof_id_type pmax_node_id = mesh.max_node_id();
1690  mesh.comm().max(pmax_node_id);
1691 
1692  for (dof_id_type i=0; i != pmax_node_id; ++i)
1693  {
1694  const Point * p = mesh.query_node_ptr(i);
1695 
1697  }
1698 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
virtual const Node * query_node_ptr(const dof_id_type i) const =0
libmesh_assert(ctx)
timpi_pure bool semiverify(const T *r) const
void max(const T &r, T &o, Request &req) const
virtual dof_id_type max_node_id() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_no_links_to_elem()

void libMesh::MeshTools::libmesh_assert_no_links_to_elem ( const MeshBase mesh,
const Elem bad_elem 
)

The following functions, only available in builds with DEBUG defined, typically have surprisingly slow asymptotic behavior, and so are unsuitable for use even with METHOD=devel.

A function for verifying that an element has been cut off from the rest of the mesh

Definition at line 1666 of file mesh_tools.C.

References libMesh::libmesh_assert(), and mesh.

1668 {
1669  for (const auto & elem : mesh.element_ptr_range())
1670  {
1671  libmesh_assert (elem);
1672  libmesh_assert_not_equal_to (elem->parent(), bad_elem);
1673  for (auto n : elem->neighbor_ptr_range())
1674  libmesh_assert_not_equal_to (n, bad_elem);
1675 
1676 #ifdef LIBMESH_ENABLE_AMR
1677  if (elem->has_children())
1678  for (auto & child : elem->child_ref_range())
1679  libmesh_assert_not_equal_to (&child, bad_elem);
1680 #endif
1681  }
1682 }
MeshBase & mesh
Definition: mesh_tools.C:2393
libmesh_assert(ctx)

◆ libmesh_assert_old_dof_objects()

void libMesh::MeshTools::libmesh_assert_old_dof_objects ( const MeshBase mesh)

A function for testing that all non-recently-created DofObjects within a mesh have old_dof_object data.

This is not expected to be true at all points within a simulation code.

Definition at line 1318 of file mesh_tools.C.

References libMesh::Elem::INACTIVE, libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), and mesh.

1319 {
1320  LOG_SCOPE("libmesh_assert_old_dof_objects()", "MeshTools");
1321 
1322  for (const auto & elem : mesh.element_ptr_range())
1323  {
1324  if (elem->refinement_flag() == Elem::JUST_REFINED ||
1325  elem->refinement_flag() == Elem::INACTIVE)
1326  continue;
1327 
1328  if (elem->has_dofs())
1329  libmesh_assert(elem->get_old_dof_object());
1330 
1331  for (auto & node : elem->node_ref_range())
1332  if (node.has_dofs())
1333  libmesh_assert(node.get_old_dof_object());
1334  }
1335 }
MeshBase & mesh
Definition: mesh_tools.C:2393
libmesh_assert(ctx)

◆ libmesh_assert_parallel_consistent_new_node_procids()

void libMesh::MeshTools::libmesh_assert_parallel_consistent_new_node_procids ( const MeshBase mesh)

A function for verifying that processor assignment is parallel consistent (every processor agrees on the processor id of each node it can see) even on nodes which have not yet received consistent DofObject::id(), using element topology to identify matching nodes.

Definition at line 2180 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), mesh, n_nodes(), libMesh::Elem::n_nodes(), libMesh::ParallelObject::n_processors(), libMesh::Elem::node_ptr(), libMesh::DofObject::processor_id(), libMesh::MeshBase::query_elem_ptr(), and TIMPI::Communicator::semiverify().

Referenced by libMesh::MeshCommunication::make_new_node_proc_ids_parallel_consistent().

2181 {
2182  LOG_SCOPE("libmesh_assert_parallel_consistent_new_node_procids()", "MeshTools");
2183 
2184  if (mesh.n_processors() == 1)
2185  return;
2186 
2187  libmesh_parallel_only(mesh.comm());
2188 
2189  // We want this test to hit every node when called even after nodes
2190  // have been added asynchronously but before everything has been
2191  // renumbered.
2192  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
2193  mesh.comm().max(parallel_max_elem_id);
2194 
2195  std::vector<bool> elem_touched_by_anyone(parallel_max_elem_id, false);
2196 
2197  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2198  {
2199  const Elem * elem = mesh.query_elem_ptr(i);
2200 
2201  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
2202  unsigned int n_nodes = my_n_nodes;
2203  mesh.comm().max(n_nodes);
2204 
2205  if (n_nodes)
2206  libmesh_assert(mesh.comm().semiverify(elem ? &my_n_nodes : nullptr));
2207 
2208  for (unsigned int n=0; n != n_nodes; ++n)
2209  {
2210  const Node * node = elem ? elem->node_ptr(n) : nullptr;
2211  const processor_id_type pid = node ? node->processor_id() : 0;
2212  libmesh_assert(mesh.comm().semiverify (node ? &pid : nullptr));
2213  }
2214  }
2215 }
A Node is like a Point, but with more information.
Definition: node.h:52
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
uint8_t processor_id_type
processor_id_type n_processors() const
const dof_id_type n_nodes
Definition: tecplot_io.C:67
virtual unsigned int n_nodes() const =0
virtual dof_id_type max_elem_id() const =0
libmesh_assert(ctx)
timpi_pure bool semiverify(const T *r) const
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2513
processor_id_type processor_id() const
Definition: dof_object.h:881
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_parallel_consistent_procids()

template<typename DofObjectSubclass >
void libMesh::MeshTools::libmesh_assert_parallel_consistent_procids ( const MeshBase mesh)

A function for verifying that processor assignment is parallel consistent (every processor agrees on the processor id of each dof object it can see)

◆ libmesh_assert_parallel_consistent_procids< Elem >()

Definition at line 2132 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), mesh, TIMPI::Communicator::min(), libMesh::ParallelObject::n_processors(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), and libMesh::MeshBase::query_elem_ptr().

2133 {
2134  LOG_SCOPE("libmesh_assert_parallel_consistent_procids()", "MeshTools");
2135 
2136  if (mesh.n_processors() == 1)
2137  return;
2138 
2139  libmesh_parallel_only(mesh.comm());
2140 
2141  // Some code (looking at you, stitch_meshes) modifies DofObject ids
2142  // without keeping max_elem_id()/max_node_id() consistent, but
2143  // that's done in a safe way for performance reasons, so we'll play
2144  // along and just figure out new max ids ourselves.
2145  dof_id_type parallel_max_elem_id = 0;
2146  for (const auto & elem : mesh.element_ptr_range())
2147  parallel_max_elem_id = std::max<dof_id_type>(parallel_max_elem_id,
2148  elem->id()+1);
2149  mesh.comm().max(parallel_max_elem_id);
2150 
2151  // Check processor ids for consistency between processors
2152 
2153  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2154  {
2155  const Elem * elem = mesh.query_elem_ptr(i);
2156 
2157  processor_id_type min_id =
2158  elem ? elem->processor_id() :
2159  std::numeric_limits<processor_id_type>::max();
2160  mesh.comm().min(min_id);
2161 
2162  processor_id_type max_id =
2163  elem ? elem->processor_id() :
2164  std::numeric_limits<processor_id_type>::min();
2165  mesh.comm().max(max_id);
2166 
2167  if (elem)
2168  {
2169  libmesh_assert_equal_to (min_id, elem->processor_id());
2170  libmesh_assert_equal_to (max_id, elem->processor_id());
2171  }
2172 
2173  if (min_id == mesh.processor_id())
2174  libmesh_assert(elem);
2175  }
2176 }
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
uint8_t processor_id_type
processor_id_type n_processors() const
void min(const T &r, T &o, Request &req) const
libmesh_assert(ctx)
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:881
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_parallel_consistent_procids< Node >()

Definition at line 2218 of file mesh_tools.C.

References libMesh::as_range(), libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), mesh, libMesh::ParallelObject::n_processors(), libMesh::DofObject::processor_id(), libMesh::MeshBase::query_node_ptr(), and TIMPI::Communicator::semiverify().

Referenced by libMesh::UnstructuredMesh::copy_nodes_and_elements(), correct_node_proc_ids(), and libMesh::MeshCommunication::make_new_node_proc_ids_parallel_consistent().

2219 {
2220  LOG_SCOPE("libmesh_assert_parallel_consistent_procids()", "MeshTools");
2221 
2222  if (mesh.n_processors() == 1)
2223  return;
2224 
2225  libmesh_parallel_only(mesh.comm());
2226 
2227  // We want this test to be valid even when called even after nodes
2228  // have been added asynchronously but before they're renumbered
2229  //
2230  // Plus, some code (looking at you, stitch_meshes) modifies
2231  // DofObject ids without keeping max_elem_id()/max_node_id()
2232  // consistent, but that's done in a safe way for performance
2233  // reasons, so we'll play along and just figure out new max ids
2234  // ourselves.
2235  dof_id_type parallel_max_node_id = 0;
2236  for (const auto & node : mesh.node_ptr_range())
2237  parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
2238  node->id()+1);
2239  mesh.comm().max(parallel_max_node_id);
2240 
2241  std::vector<bool> node_touched_by_anyone(parallel_max_node_id, false);
2242 
2243  for (const auto & elem : as_range(mesh.local_elements_begin(),
2244  mesh.local_elements_end()))
2245  {
2246  libmesh_assert (elem);
2247 
2248  for (auto & node : elem->node_ref_range())
2249  {
2250  dof_id_type nodeid = node.id();
2251  node_touched_by_anyone[nodeid] = true;
2252  }
2253  }
2254  mesh.comm().max(node_touched_by_anyone);
2255 
2256  // Check processor ids for consistency between processors
2257  // on any node an element touches
2258  for (dof_id_type i=0; i != parallel_max_node_id; ++i)
2259  {
2260  if (!node_touched_by_anyone[i])
2261  continue;
2262 
2263  const Node * node = mesh.query_node_ptr(i);
2264  const processor_id_type pid = node ? node->processor_id() : 0;
2265 
2266  libmesh_assert(mesh.comm().semiverify (node ? &pid : nullptr));
2267  }
2268 }
A Node is like a Point, but with more information.
Definition: node.h:52
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
uint8_t processor_id_type
processor_id_type n_processors() const
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
virtual const Node * query_node_ptr(const dof_id_type i) const =0
libmesh_assert(ctx)
timpi_pure bool semiverify(const T *r) const
void max(const T &r, T &o, Request &req) const
processor_id_type processor_id() const
Definition: dof_object.h:881
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_topology_consistent_procids()

template<typename DofObjectSubclass >
void libMesh::MeshTools::libmesh_assert_topology_consistent_procids ( const MeshBase mesh)

A function for verifying that processor assignment is topologically consistent on nodes (each node part of an active element on its processor) or elements (each parent has the processor id of one of its children).

◆ libmesh_assert_topology_consistent_procids< Elem >()

Definition at line 1519 of file mesh_tools.C.

References libMesh::Elem::child_ref_range(), libMesh::Elem::has_children(), libMesh::libmesh_assert(), libMesh::libmesh_ignore(), mesh, libMesh::Elem::parent(), libMesh::DofObject::processor_id(), and libMesh::remote_elem.

1520 {
1521  LOG_SCOPE("libmesh_assert_topology_consistent_procids()", "MeshTools");
1522 
1523  // This parameter is not used when !LIBMESH_ENABLE_AMR
1525 
1526  // If we're adaptively refining, check processor ids for consistency
1527  // between parents and children.
1528 #ifdef LIBMESH_ENABLE_AMR
1529 
1530  // Ancestor elements we won't worry about, but subactive and active
1531  // elements ought to have parents with consistent processor ids
1532  for (const auto & elem : mesh.element_ptr_range())
1533  {
1534  libmesh_assert(elem);
1535 
1536  if (!elem->active() && !elem->subactive())
1537  continue;
1538 
1539  const Elem * parent = elem->parent();
1540 
1541  if (parent)
1542  {
1543  libmesh_assert(parent->has_children());
1544  processor_id_type parent_procid = parent->processor_id();
1545  bool matching_child_id = false;
1546  // If we've got a remote_elem then we don't know whether
1547  // it's responsible for the parent's processor id; all
1548  // we can do is assume it is and let its processor fail
1549  // an assert if there's something wrong.
1550  for (auto & child : parent->child_ref_range())
1551  if (&child == remote_elem ||
1552  child.processor_id() == parent_procid)
1553  matching_child_id = true;
1554  libmesh_assert(matching_child_id);
1555  }
1556  }
1557 #endif
1558 }
const Elem * parent() const
Definition: elem.h:3044
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2393
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:2352
uint8_t processor_id_type
void libmesh_ignore(const Args &...)
libmesh_assert(ctx)
processor_id_type processor_id() const
Definition: dof_object.h:881
bool has_children() const
Definition: elem.h:2993
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ libmesh_assert_topology_consistent_procids< Node >()

Definition at line 1563 of file mesh_tools.C.

References libMesh::as_range(), libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), mesh, and libMesh::ParallelObject::n_processors().

Referenced by libMesh::MeshCommunication::make_node_ids_parallel_consistent().

1564 {
1565  LOG_SCOPE("libmesh_assert_topology_consistent_procids()", "MeshTools");
1566 
1567  if (mesh.n_processors() == 1)
1568  return;
1569 
1570  libmesh_parallel_only(mesh.comm());
1571 
1572  // We want this test to be valid even when called after nodes have
1573  // been added asynchronously but before they're renumbered.
1574  //
1575  // Plus, some code (looking at you, stitch_meshes) modifies
1576  // DofObject ids without keeping max_elem_id()/max_node_id()
1577  // consistent, but that's done in a safe way for performance
1578  // reasons, so we'll play along and just figure out new max ids
1579  // ourselves.
1580  dof_id_type parallel_max_node_id = 0;
1581  for (const auto & node : mesh.node_ptr_range())
1582  parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
1583  node->id()+1);
1584  mesh.comm().max(parallel_max_node_id);
1585 
1586 
1587  std::vector<bool> node_touched_by_me(parallel_max_node_id, false);
1588 
1589  for (const auto & elem : as_range(mesh.local_elements_begin(),
1590  mesh.local_elements_end()))
1591  {
1592  libmesh_assert (elem);
1593 
1594  for (auto & node : elem->node_ref_range())
1595  {
1596  dof_id_type nodeid = node.id();
1597  node_touched_by_me[nodeid] = true;
1598  }
1599  }
1600  std::vector<bool> node_touched_by_anyone(node_touched_by_me);
1601  mesh.comm().max(node_touched_by_anyone);
1602 
1603  for (const auto & node : mesh.local_node_ptr_range())
1604  {
1605  libmesh_assert(node);
1606  dof_id_type nodeid = node->id();
1607  libmesh_assert(!node_touched_by_anyone[nodeid] ||
1608  node_touched_by_me[nodeid]);
1609  }
1610 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
processor_id_type n_processors() const
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_assert(ctx)
void max(const T &r, T &o, Request &req) const
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_valid_amr_elem_ids()

void libMesh::MeshTools::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 than children)

Definition at line 1421 of file mesh_tools.C.

References libMesh::DofObject::id(), libMesh::libmesh_assert(), mesh, libMesh::Elem::parent(), and libMesh::DofObject::processor_id().

Referenced by libMesh::UnstructuredMesh::copy_nodes_and_elements().

1422 {
1423  LOG_SCOPE("libmesh_assert_valid_amr_elem_ids()", "MeshTools");
1424 
1425  for (const auto & elem : mesh.element_ptr_range())
1426  {
1427  libmesh_assert (elem);
1428 
1429  const Elem * parent = elem->parent();
1430 
1431  if (parent)
1432  {
1433  libmesh_assert_greater_equal (elem->id(), parent->id());
1434  libmesh_assert_greater_equal (elem->processor_id(), parent->processor_id());
1435  }
1436  }
1437 }
const Elem * parent() const
Definition: elem.h:3044
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2393
dof_id_type id() const
Definition: dof_object.h:819
libmesh_assert(ctx)
processor_id_type processor_id() const
Definition: dof_object.h:881

◆ libmesh_assert_valid_amr_interior_parents()

void libMesh::MeshTools::libmesh_assert_valid_amr_interior_parents ( const MeshBase mesh)

A function for verifying that any interior_parent pointers on elements are consistent with AMR (parents' interior_parents are interior_parents' parents)

Definition at line 1441 of file mesh_tools.C.

References libMesh::Elem::interior_parent(), libMesh::Elem::level(), libMesh::libmesh_assert(), mesh, libMesh::Elem::parent(), libMesh::remote_elem, and libMesh::Elem::top_parent().

Referenced by libMesh::UnstructuredMesh::find_neighbors().

1442 {
1443  LOG_SCOPE("libmesh_assert_valid_amr_interior_parents()", "MeshTools");
1444 
1445  for (const auto & elem : mesh.element_ptr_range())
1446  {
1447  libmesh_assert (elem);
1448 
1449  // We can skip to the next element if we're full-dimension
1450  // and therefore don't have any interior parents
1451  if (elem->dim() >= LIBMESH_DIM)
1452  continue;
1453 
1454  const Elem * ip = elem->interior_parent();
1455 
1456  const Elem * parent = elem->parent();
1457 
1458  if (ip && (ip != remote_elem) && parent)
1459  {
1460  libmesh_assert_equal_to (ip->top_parent(),
1461  elem->top_parent()->interior_parent());
1462 
1463  if (ip->level() == elem->level())
1464  libmesh_assert_equal_to (ip->parent(),
1465  parent->interior_parent());
1466  else
1467  {
1468  libmesh_assert_less (ip->level(), elem->level());
1469  libmesh_assert_equal_to (ip, parent->interior_parent());
1470  }
1471  }
1472  }
1473 }
const Elem * parent() const
Definition: elem.h:3044
const Elem * interior_parent() const
Definition: elem.C:1160
const Elem * top_parent() const
Definition: elem.h:3070
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2393
libmesh_assert(ctx)
unsigned int level() const
Definition: elem.h:3088
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ libmesh_assert_valid_boundary_ids()

void libMesh::MeshTools::libmesh_assert_valid_boundary_ids ( const MeshBase mesh)

A function for verifying that boundary condition ids match across processors.

Definition at line 1788 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::MeshBase::get_boundary_info(), libMesh::BoundaryInfo::invalid_id, libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), mesh, libMesh::Elem::n_edges(), n_nodes(), libMesh::Elem::n_nodes(), libMesh::ParallelObject::n_processors(), libMesh::Elem::n_sides(), libMesh::Elem::node_ptr(), libMesh::MeshBase::query_elem_ptr(), and TIMPI::Communicator::semiverify().

Referenced by libMesh::MeshBase::complete_preparation(), and libMesh::DofMap::create_dof_constraints().

1789 {
1790  LOG_SCOPE("libmesh_assert_valid_boundary_ids()", "MeshTools");
1791 
1792  if (mesh.n_processors() == 1)
1793  return;
1794 
1795  libmesh_parallel_only(mesh.comm());
1796 
1797  const BoundaryInfo & boundary_info = mesh.get_boundary_info();
1798 
1799  dof_id_type pmax_elem_id = mesh.max_elem_id();
1800  mesh.comm().max(pmax_elem_id);
1801 
1802  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1803  {
1804  const Elem * elem = mesh.query_elem_ptr(i);
1805  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
1806  const unsigned int my_n_edges = elem ? elem->n_edges() : 0;
1807  const unsigned int my_n_sides = elem ? elem->n_sides() : 0;
1808  unsigned int
1809  n_nodes = my_n_nodes,
1810  n_edges = my_n_edges,
1811  n_sides = my_n_sides;
1812 
1813  mesh.comm().max(n_nodes);
1814  mesh.comm().max(n_edges);
1815  mesh.comm().max(n_sides);
1816 
1817  if (elem)
1818  {
1819  libmesh_assert_equal_to(my_n_nodes, n_nodes);
1820  libmesh_assert_equal_to(my_n_edges, n_edges);
1821  libmesh_assert_equal_to(my_n_sides, n_sides);
1822  }
1823 
1824  // Let's test all IDs on the element with one communication
1825  // rather than n_nodes + n_edges + n_sides communications, to
1826  // cut down on latency in dbg modes.
1827  std::vector<boundary_id_type> all_bcids;
1828 
1829  for (unsigned int n=0; n != n_nodes; ++n)
1830  {
1831  std::vector<boundary_id_type> bcids;
1832  if (elem)
1833  {
1834  boundary_info.boundary_ids(elem->node_ptr(n), bcids);
1835 
1836  // Ordering of boundary ids shouldn't matter
1837  std::sort(bcids.begin(), bcids.end());
1838  }
1839  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1840 
1841  all_bcids.insert(all_bcids.end(), bcids.begin(),
1842  bcids.end());
1843  // Separator
1844  all_bcids.push_back(BoundaryInfo::invalid_id);
1845  }
1846 
1847  for (unsigned short e=0; e != n_edges; ++e)
1848  {
1849  std::vector<boundary_id_type> bcids;
1850 
1851  if (elem)
1852  {
1853  boundary_info.edge_boundary_ids(elem, e, bcids);
1854 
1855  // Ordering of boundary ids shouldn't matter
1856  std::sort(bcids.begin(), bcids.end());
1857  }
1858 
1859  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1860 
1861  all_bcids.insert(all_bcids.end(), bcids.begin(),
1862  bcids.end());
1863  // Separator
1864  all_bcids.push_back(BoundaryInfo::invalid_id);
1865 
1866  if (elem)
1867  {
1868  boundary_info.raw_edge_boundary_ids(elem, e, bcids);
1869 
1870  // Ordering of boundary ids shouldn't matter
1871  std::sort(bcids.begin(), bcids.end());
1872 
1873  all_bcids.insert(all_bcids.end(), bcids.begin(),
1874  bcids.end());
1875  // Separator
1876  all_bcids.push_back(BoundaryInfo::invalid_id);
1877  }
1878 
1879  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1880  }
1881 
1882  for (unsigned short s=0; s != n_sides; ++s)
1883  {
1884  std::vector<boundary_id_type> bcids;
1885 
1886  if (elem)
1887  {
1888  boundary_info.boundary_ids(elem, s, bcids);
1889 
1890  // Ordering of boundary ids shouldn't matter
1891  std::sort(bcids.begin(), bcids.end());
1892 
1893  all_bcids.insert(all_bcids.end(), bcids.begin(),
1894  bcids.end());
1895  // Separator
1896  all_bcids.push_back(BoundaryInfo::invalid_id);
1897  }
1898 
1899  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1900 
1901  if (elem)
1902  {
1903  boundary_info.raw_boundary_ids(elem, s, bcids);
1904 
1905  // Ordering of boundary ids shouldn't matter
1906  std::sort(bcids.begin(), bcids.end());
1907 
1908  all_bcids.insert(all_bcids.end(), bcids.begin(),
1909  bcids.end());
1910  // Separator
1911  all_bcids.push_back(BoundaryInfo::invalid_id);
1912  }
1913 
1914  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1915  }
1916 
1917  for (unsigned short sf=0; sf != 2; ++sf)
1918  {
1919  std::vector<boundary_id_type> bcids;
1920 
1921  if (elem)
1922  {
1923  boundary_info.shellface_boundary_ids(elem, sf, bcids);
1924 
1925  // Ordering of boundary ids shouldn't matter
1926  std::sort(bcids.begin(), bcids.end());
1927 
1928  all_bcids.insert(all_bcids.end(), bcids.begin(),
1929  bcids.end());
1930  // Separator
1931  all_bcids.push_back(BoundaryInfo::invalid_id);
1932  }
1933 
1934  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1935 
1936  if (elem)
1937  {
1938  boundary_info.raw_shellface_boundary_ids(elem, sf, bcids);
1939 
1940  // Ordering of boundary ids shouldn't matter
1941  std::sort(bcids.begin(), bcids.end());
1942 
1943  all_bcids.insert(all_bcids.end(), bcids.begin(),
1944  bcids.end());
1945  // Separator
1946  all_bcids.push_back(BoundaryInfo::invalid_id);
1947  }
1948 
1949  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1950  }
1951 
1953  (elem ? &all_bcids : nullptr));
1954  }
1955 }
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:170
processor_id_type n_processors() const
const dof_id_type n_nodes
Definition: tecplot_io.C:67
virtual unsigned int n_nodes() const =0
virtual dof_id_type max_elem_id() const =0
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
virtual unsigned int n_edges() const =0
timpi_pure bool semiverify(const T *r) const
virtual unsigned int n_sides() const =0
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2513
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_valid_constraint_rows()

void libMesh::MeshTools::libmesh_assert_valid_constraint_rows ( const MeshBase mesh)

A function for verifying that all mesh constraint rows express relations between nodes and elements that are semilocal (local or ghosted) to the current processor's portion of the mesh.

Definition at line 1745 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::MeshBase::elem_ptr(), libMesh::MeshBase::get_constraint_rows(), libMesh::DofObject::id(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_node_id(), mesh, libMesh::MeshBase::node_ptr(), libMesh::MeshBase::query_node_ptr(), and TIMPI::Communicator::semiverify().

Referenced by libMesh::MeshBase::complete_preparation(), and libMesh::MeshCommunication::delete_remote_elements().

1746 {
1747  libmesh_parallel_only(mesh.comm());
1748 
1749  const auto & constraint_rows = mesh.get_constraint_rows();
1750 
1751  bool have_constraint_rows = !constraint_rows.empty();
1752  mesh.comm().max(have_constraint_rows);
1753  if (!have_constraint_rows)
1754  return;
1755 
1756  for (auto & row : constraint_rows)
1757  {
1758  const Node * node = row.first;
1759  libmesh_assert(node == mesh.node_ptr(node->id()));
1760 
1761  for (auto & pr : row.second)
1762  {
1763  const Elem * spline_elem = pr.first.first;
1764  libmesh_assert(spline_elem == mesh.elem_ptr(spline_elem->id()));
1765  }
1766  }
1767 
1768  dof_id_type pmax_node_id = mesh.max_node_id();
1769  mesh.comm().max(pmax_node_id);
1770 
1771  for (dof_id_type i=0; i != pmax_node_id; ++i)
1772  {
1773  const Node * node = mesh.query_node_ptr(i);
1774 
1775  bool have_constraint = constraint_rows.count(node);
1776 
1777  const std::size_t my_n_constraints = have_constraint ?
1778  libmesh_map_find(constraint_rows, node).size() : std::size_t(-1);
1779  const std::size_t * n_constraints = node ?
1780  &my_n_constraints : nullptr;
1781 
1782  libmesh_assert(mesh.comm().semiverify(n_constraints));
1783  }
1784 }
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1905
A Node is like a Point, but with more information.
Definition: node.h:52
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
dof_id_type id() const
Definition: dof_object.h:819
virtual const Node * query_node_ptr(const dof_id_type i) const =0
libmesh_assert(ctx)
timpi_pure bool semiverify(const T *r) const
virtual const Elem * elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
virtual dof_id_type max_node_id() const =0
virtual const Node * node_ptr(const dof_id_type i) const =0
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_valid_dof_ids()

void libMesh::MeshTools::libmesh_assert_valid_dof_ids ( const MeshBase mesh,
unsigned int  sysnum = libMesh::invalid_uint 
)

A function for verifying that degree of freedom indexing matches across processors.

Verify a particular system by specifying that system's number, or verify all systems at once by leaving sysnum unspecified.

Definition at line 1958 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::max_node_id(), mesh, libMesh::ParallelObject::n_processors(), libMesh::MeshBase::query_elem_ptr(), and libMesh::MeshBase::query_node_ptr().

Referenced by libMesh::DofMap::distribute_dofs().

1959 {
1960  LOG_SCOPE("libmesh_assert_valid_dof_ids()", "MeshTools");
1961 
1962  if (mesh.n_processors() == 1)
1963  return;
1964 
1965  libmesh_parallel_only(mesh.comm());
1966 
1967  dof_id_type pmax_elem_id = mesh.max_elem_id();
1968  mesh.comm().max(pmax_elem_id);
1969 
1970  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1971  assert_semiverify_dofobj(mesh.comm(),
1972  mesh.query_elem_ptr(i),
1973  sysnum);
1974 
1975  dof_id_type pmax_node_id = mesh.max_node_id();
1976  mesh.comm().max(pmax_node_id);
1977 
1978  for (dof_id_type i=0; i != pmax_node_id; ++i)
1979  assert_semiverify_dofobj(mesh.comm(),
1980  mesh.query_node_ptr(i),
1981  sysnum);
1982 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
processor_id_type n_processors() const
virtual const Node * query_node_ptr(const dof_id_type i) const =0
virtual dof_id_type max_elem_id() const =0
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
virtual dof_id_type max_node_id() const =0
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_valid_elem_ids()

void libMesh::MeshTools::libmesh_assert_valid_elem_ids ( const MeshBase mesh)

A function for verifying that ids and processor assignment of elements are correctly sorted (monotone increasing)

Definition at line 1398 of file mesh_tools.C.

References libMesh::libmesh_assert(), and mesh.

Referenced by libMesh::DistributedMesh::renumber_nodes_and_elements().

1399 {
1400  LOG_SCOPE("libmesh_assert_valid_elem_ids()", "MeshTools");
1401 
1402  processor_id_type lastprocid = 0;
1403  dof_id_type lastelemid = 0;
1404 
1405  for (const auto & elem : mesh.active_element_ptr_range())
1406  {
1407  libmesh_assert (elem);
1408  processor_id_type elemprocid = elem->processor_id();
1409  dof_id_type elemid = elem->id();
1410 
1411  libmesh_assert_greater_equal (elemid, lastelemid);
1412  libmesh_assert_greater_equal (elemprocid, lastprocid);
1413 
1414  lastelemid = elemid;
1415  lastprocid = elemprocid;
1416  }
1417 }
MeshBase & mesh
Definition: mesh_tools.C:2393
uint8_t processor_id_type
libmesh_assert(ctx)
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_valid_neighbors()

void libMesh::MeshTools::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 descendant of a neighbor of its neighbors) and consistent (each neighbor link goes to either the same neighbor or to a RemoteElem on each processor)

If assert_valid_remote_elems is set to false, then no error will be thrown for neighbor links where a remote_elem should exist but a nullptr exists instead.

Definition at line 2320 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::DofObject::id(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), mesh, libMesh::Elem::n_neighbors(), libMesh::ParallelObject::n_processors(), libMesh::Elem::neighbor_ptr(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), libMesh::MeshBase::query_elem_ptr(), libMesh::remote_elem, and TIMPI::Communicator::semiverify().

Referenced by libMesh::MeshRefinement::_smooth_flags(), libMesh::DistributedMesh::allgather(), libMesh::DistributedMesh::delete_remote_elements(), libMesh::UnstructuredMesh::find_neighbors(), and libMesh::UnstructuredMesh::stitching_helper().

2322 {
2323  LOG_SCOPE("libmesh_assert_valid_neighbors()", "MeshTools");
2324 
2325  for (const auto & elem : mesh.element_ptr_range())
2326  {
2327  libmesh_assert (elem);
2328  elem->libmesh_assert_valid_neighbors();
2329  }
2330 
2331  if (mesh.n_processors() == 1)
2332  return;
2333 
2334  libmesh_parallel_only(mesh.comm());
2335 
2336  dof_id_type pmax_elem_id = mesh.max_elem_id();
2337  mesh.comm().max(pmax_elem_id);
2338 
2339  for (dof_id_type i=0; i != pmax_elem_id; ++i)
2340  {
2341  const Elem * elem = mesh.query_elem_ptr(i);
2342 
2343  const unsigned int my_n_neigh = elem ? elem->n_neighbors() : 0;
2344  unsigned int n_neigh = my_n_neigh;
2345  mesh.comm().max(n_neigh);
2346  if (elem)
2347  libmesh_assert_equal_to (my_n_neigh, n_neigh);
2348 
2349  for (unsigned int n = 0; n != n_neigh; ++n)
2350  {
2351  dof_id_type my_neighbor = DofObject::invalid_id;
2352  dof_id_type * p_my_neighbor = nullptr;
2353 
2354  // If we have a non-remote_elem neighbor link, then we can
2355  // verify it.
2356  if (elem && elem->neighbor_ptr(n) != remote_elem)
2357  {
2358  p_my_neighbor = &my_neighbor;
2359  if (elem->neighbor_ptr(n))
2360  my_neighbor = elem->neighbor_ptr(n)->id();
2361 
2362  // But wait - if we haven't set remote_elem links yet then
2363  // some nullptr links on ghost elements might be
2364  // future-remote_elem links, so we can't verify those.
2365  if (!assert_valid_remote_elems &&
2366  !elem->neighbor_ptr(n) &&
2367  elem->processor_id() != mesh.processor_id())
2368  p_my_neighbor = nullptr;
2369  }
2370  libmesh_assert(mesh.comm().semiverify(p_my_neighbor));
2371  }
2372  }
2373 }
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
processor_id_type n_processors() const
dof_id_type id() const
Definition: dof_object.h:819
virtual dof_id_type max_elem_id() const =0
libmesh_assert(ctx)
timpi_pure bool semiverify(const T *r) const
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2612
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
unsigned int n_neighbors() const
Definition: elem.h:713
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:881
uint8_t dof_id_type
Definition: id_types.h:67
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ libmesh_assert_valid_node_pointers()

void libMesh::MeshTools::libmesh_assert_valid_node_pointers ( const MeshBase mesh)

A function for walking across the mesh to try and ferret out invalidated or misassigned pointers.

Definition at line 1342 of file mesh_tools.C.

References libMesh::libmesh_assert(), mesh, and libMesh::remote_elem.

1343 {
1344  LOG_SCOPE("libmesh_assert_valid_node_pointers()", "MeshTools");
1345 
1346  // Here we specifically do not want "auto &" because we need to
1347  // reseat the (temporary) pointer variable in the loop below,
1348  // without modifying the original.
1349  for (const Elem * elem : mesh.element_ptr_range())
1350  {
1351  libmesh_assert (elem);
1352  while (elem)
1353  {
1354  elem->libmesh_assert_valid_node_pointers();
1355  for (auto n : elem->neighbor_ptr_range())
1356  if (n && n != remote_elem)
1357  n->libmesh_assert_valid_node_pointers();
1358 
1359  libmesh_assert_not_equal_to (elem->parent(), remote_elem);
1360  elem = elem->parent();
1361  }
1362  }
1363 }
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2393
libmesh_assert(ctx)
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ libmesh_assert_valid_procids()

template<typename DofObjectSubclass >
void libMesh::MeshTools::libmesh_assert_valid_procids ( const MeshBase mesh)

A function for verifying that processor assignment is both parallel and topologically consistent.

Definition at line 599 of file mesh_tools.h.

References mesh.

600 {
601  libmesh_assert_parallel_consistent_procids<DofObjectSubclass>(mesh);
602  libmesh_assert_topology_consistent_procids<DofObjectSubclass>(mesh);
603 }
MeshBase & mesh

◆ libmesh_assert_valid_refinement_flags()

void libMesh::MeshTools::libmesh_assert_valid_refinement_flags ( const MeshBase mesh)

A function for verifying that refinement flags on elements are consistent between processors.

Definition at line 2273 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), mesh, TIMPI::Communicator::min(), and libMesh::ParallelObject::n_processors().

2274 {
2275  LOG_SCOPE("libmesh_assert_valid_refinement_flags()", "MeshTools");
2276 
2277  libmesh_parallel_only(mesh.comm());
2278  if (mesh.n_processors() == 1)
2279  return;
2280 
2281  dof_id_type pmax_elem_id = mesh.max_elem_id();
2282  mesh.comm().max(pmax_elem_id);
2283 
2284  std::vector<unsigned char> my_elem_h_state(pmax_elem_id, 255);
2285  std::vector<unsigned char> my_elem_p_state(pmax_elem_id, 255);
2286 
2287  for (const auto & elem : mesh.element_ptr_range())
2288  {
2289  libmesh_assert (elem);
2290  dof_id_type elemid = elem->id();
2291 
2292  my_elem_h_state[elemid] =
2293  static_cast<unsigned char>(elem->refinement_flag());
2294 
2295  my_elem_p_state[elemid] =
2296  static_cast<unsigned char>(elem->p_refinement_flag());
2297  }
2298  std::vector<unsigned char> min_elem_h_state(my_elem_h_state);
2299  mesh.comm().min(min_elem_h_state);
2300 
2301  std::vector<unsigned char> min_elem_p_state(my_elem_p_state);
2302  mesh.comm().min(min_elem_p_state);
2303 
2304  for (dof_id_type i=0; i!= pmax_elem_id; ++i)
2305  {
2306  libmesh_assert(my_elem_h_state[i] == 255 ||
2307  my_elem_h_state[i] == min_elem_h_state[i]);
2308  libmesh_assert(my_elem_p_state[i] == 255 ||
2309  my_elem_p_state[i] == min_elem_p_state[i]);
2310  }
2311 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
processor_id_type n_processors() const
void min(const T &r, T &o, Request &req) const
virtual dof_id_type max_elem_id() const =0
libmesh_assert(ctx)
void max(const T &r, T &o, Request &req) const
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_valid_refinement_tree()

void libMesh::MeshTools::libmesh_assert_valid_refinement_tree ( const MeshBase mesh)

A function for verifying that elements on this processor have valid descendants and consistent active flags.

Definition at line 1627 of file mesh_tools.C.

References libMesh::Elem::JUST_REFINED, libMesh::libmesh_assert(), mesh, and libMesh::remote_elem.

Referenced by libMesh::MeshCommunication::delete_remote_elements(), and libMesh::DistributedMesh::delete_remote_elements().

1628 {
1629  LOG_SCOPE("libmesh_assert_valid_refinement_tree()", "MeshTools");
1630 
1631  for (const auto & elem : mesh.element_ptr_range())
1632  {
1633  libmesh_assert(elem);
1634  if (elem->has_children())
1635  for (auto & child : elem->child_ref_range())
1636  if (&child != remote_elem)
1637  libmesh_assert_equal_to (child.parent(), elem);
1638  if (elem->active())
1639  {
1640  libmesh_assert(!elem->ancestor());
1641  libmesh_assert(!elem->subactive());
1642  }
1643  else if (elem->ancestor())
1644  {
1645  libmesh_assert(!elem->subactive());
1646  }
1647  else
1648  libmesh_assert(elem->subactive());
1649 
1650  if (elem->p_refinement_flag() == Elem::JUST_REFINED)
1651  libmesh_assert_greater(elem->p_level(), 0);
1652  }
1653 }
MeshBase & mesh
Definition: mesh_tools.C:2393
libmesh_assert(ctx)
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ libmesh_assert_valid_remote_elems()

void libMesh::MeshTools::libmesh_assert_valid_remote_elems ( const MeshBase mesh)

A function for verifying that active local elements' neighbors are never remote elements.

Definition at line 1367 of file mesh_tools.C.

References libMesh::as_range(), libMesh::libmesh_assert(), mesh, libMesh::Elem::parent(), and libMesh::remote_elem.

Referenced by libMesh::Partitioner::partition().

1368 {
1369  LOG_SCOPE("libmesh_assert_valid_remote_elems()", "MeshTools");
1370 
1371  for (const auto & elem : as_range(mesh.local_elements_begin(),
1372  mesh.local_elements_end()))
1373  {
1374  libmesh_assert (elem);
1375 
1376  // We currently don't allow active_local_elements to have
1377  // remote_elem neighbors
1378  if (elem->active())
1379  for (auto n : elem->neighbor_ptr_range())
1380  libmesh_assert_not_equal_to (n, remote_elem);
1381 
1382 #ifdef LIBMESH_ENABLE_AMR
1383  const Elem * parent = elem->parent();
1384  if (parent)
1385  libmesh_assert_not_equal_to (parent, remote_elem);
1386 
1387  // We can only be strict about active elements' subactive
1388  // children
1389  if (elem->active() && elem->has_children())
1390  for (auto & child : elem->child_ref_range())
1391  libmesh_assert_not_equal_to (&child, remote_elem);
1392 #endif
1393  }
1394 }
const Elem * parent() const
Definition: elem.h:3044
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2393
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_assert(ctx)
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ libmesh_assert_valid_unique_ids()

void libMesh::MeshTools::libmesh_assert_valid_unique_ids ( const MeshBase mesh)

A function for verifying that unique ids match across processors.

Definition at line 1986 of file mesh_tools.C.

References libMesh::MeshBase::allow_node_and_elem_unique_id_overlap(), libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::libmesh_ignore(), libMesh::make_range(), TIMPI::Communicator::max(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::max_node_id(), mesh, libMesh::MeshBase::query_elem_ptr(), and libMesh::MeshBase::query_node_ptr().

Referenced by libMesh::MeshBase::complete_preparation(), and libMesh::SimplexRefiner::refine_via_edges().

1987 {
1988  LOG_SCOPE("libmesh_assert_valid_unique_ids()", "MeshTools");
1989 
1990  libmesh_parallel_only(mesh.comm());
1991 
1992  // Storage for semi-local DofObject ids.
1993  std::unordered_set<unique_id_type> semilocal_unique_ids;
1994 
1995  auto gather_elem_ids = [&]()
1996  {
1997  for (auto const & elem : mesh.active_element_ptr_range())
1998  {
1999  auto [it, inserted] = semilocal_unique_ids.insert(elem->unique_id());
2000  libmesh_assert(inserted);
2001  libmesh_ignore(it);
2002  }
2003  };
2004 
2005  auto gather_node_ids = [&]()
2006  {
2007  for (auto const & node : mesh.node_ptr_range())
2008  {
2009  auto [it, inserted] = semilocal_unique_ids.insert(node->unique_id());
2010  libmesh_assert(inserted);
2011  libmesh_ignore(it);
2012  }
2013  };
2014 
2015  auto verify_elems = [&]()
2016  {
2017  dof_id_type pmax_elem_id = mesh.max_elem_id();
2018  mesh.comm().max(pmax_elem_id);
2019 
2020  for (auto i : make_range(pmax_elem_id))
2021  {
2022  const Elem * elem = mesh.query_elem_ptr(i);
2023  assert_dofobj_unique_id(mesh.comm(), elem, semilocal_unique_ids);
2024  }
2025  };
2026 
2027  auto verify_nodes = [&]()
2028  {
2029  dof_id_type pmax_node_id = mesh.max_node_id();
2030  mesh.comm().max(pmax_node_id);
2031 
2032  for (auto i : make_range(pmax_node_id))
2033  {
2034  const Node * node = mesh.query_node_ptr(i);
2035  assert_dofobj_unique_id(mesh.comm(), node, semilocal_unique_ids);
2036  }
2037  };
2038 
2040  {
2041  // First collect all the unique_ids we can see and make sure there's
2042  // no duplicates
2043  gather_elem_ids();
2044  gather_node_ids();
2045 
2046  // Then make sure elements/nodes are all in sync and remote
2047  // elements don't duplicate semilocal
2048  verify_elems();
2049  verify_nodes();
2050  }
2051  else
2052  {
2053  // If the mesh allows Node and Elem unique_ids to overlap, then we only
2054  // check for validity and uniqueness of an Elem (resp. Node) unique id
2055  // within the set of Elem (resp. Node) unique_ids.
2056  gather_elem_ids();
2057  verify_elems();
2058 
2059  // Clear id list before checking Nodes
2060  semilocal_unique_ids.clear();
2061 
2062  // Finally, check Nodes
2063  gather_node_ids();
2064  verify_nodes();
2065  }
2066 }
A Node is like a Point, but with more information.
Definition: node.h:52
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
void libmesh_ignore(const Args &...)
virtual const Node * query_node_ptr(const dof_id_type i) const =0
virtual dof_id_type max_elem_id() const =0
libmesh_assert(ctx)
void allow_node_and_elem_unique_id_overlap(bool allow)
If true is passed, then this mesh will no longer require unique_ids to be unique across the set of al...
Definition: mesh_base.h:1377
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
void max(const T &r, T &o, Request &req) const
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition: int_range.h:176
virtual dof_id_type max_node_id() const =0
uint8_t dof_id_type
Definition: id_types.h:67

◆ n_active_elem_of_type()

dof_id_type libMesh::MeshTools::n_active_elem_of_type ( const MeshBase mesh,
const ElemType  type 
)
Returns
The number of active elements of type type.

Implemented in terms of active_type_element_iterators.

Definition at line 744 of file mesh_tools.C.

References distance(), and mesh.

746 {
747  return static_cast<dof_id_type>(std::distance(mesh.active_type_elements_begin(type),
748  mesh.active_type_elements_end (type)));
749 }
MeshBase & mesh
Definition: mesh_tools.C:2393
Real distance(const Point &p)
uint8_t dof_id_type
Definition: id_types.h:67

◆ n_active_levels()

unsigned int libMesh::MeshTools::n_active_levels ( const MeshBase mesh)
Returns
The number of levels of refinement in the active mesh.

Implemented by looping over all the active local elements and finding the maximum level, then taking the max in parallel.

Definition at line 796 of file mesh_tools.C.

References libMesh::as_range(), libMesh::ParallelObject::comm(), TIMPI::Communicator::max(), mesh, and n_active_local_levels().

Referenced by libMesh::XdrIO::write_serialized_connectivity().

797 {
798  libmesh_parallel_only(mesh.comm());
799 
800  unsigned int nl = n_active_local_levels(mesh);
801 
802  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
803  mesh.unpartitioned_elements_end()))
804  if (elem->active())
805  nl = std::max(elem->level() + 1, nl);
806 
807  mesh.comm().max(nl);
808  return nl;
809 }
unsigned int n_active_local_levels(const MeshBase &mesh)
Definition: mesh_tools.C:767
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
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
void max(const T &r, T &o, Request &req) const

◆ n_active_local_levels()

unsigned int libMesh::MeshTools::n_active_local_levels ( const MeshBase mesh)
Returns
The number of levels of refinement in the active local mesh.

Implemented by looping over all the active local elements and finding the maximum level.

Definition at line 767 of file mesh_tools.C.

References libMesh::MeshBase::active_local_element_stored_range(), mesh, and libMesh::Threads::parallel_reduce().

Referenced by n_active_levels().

768 {
769  struct LevelCounter {
770  unsigned int nl;
771 
772  LevelCounter () : nl(0) {}
773 
774  LevelCounter (LevelCounter &, Threads::split) :
775  nl(0) {}
776 
777  void operator()(const ConstElemRange & range) {
778  for (const Elem * elem : range)
779  nl = std::max(elem->level() + 1, nl);
780  }
781 
782  void join(const LevelCounter & other) {
783  nl = std::max(nl, other.nl);
784  }
785  };
786 
787  LevelCounter counter;
788 
790 
791  return counter.nl;
792 }
Dummy "splitting object" used to distinguish splitting constructors from copy constructors.
Definition: threads_none.h:63
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2393
const ConstElemRange & active_local_element_stored_range() const
Definition: mesh_base.C:1928
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:109

◆ n_connected_components()

dof_id_type libMesh::MeshTools::n_connected_components ( const MeshBase mesh,
Real  constraint_tol = 0 
)
Returns
The number of topologically connected components in the mesh, where a local connection is defined as two nodes connected to the same element, two elements connected to the same node, and/or two nodes connected by a constraint row; thus a connection can be made at a single vertex, not just at an element side.

To count sufficiently weak constraint row coefficients as a lack-of-connection, set a constraint_tol greater than 0.

Definition at line 864 of file mesh_tools.C.

References TIMPI::Communicator::broadcast(), libMesh::ParallelObject::comm(), libMesh::MeshBase::elem_ptr(), libMesh::MeshBase::get_constraint_rows(), libMesh::DofObject::id(), libMesh::MeshBase::is_serial_on_zero(), libMesh::libmesh_assert(), mesh, libMesh::Elem::node_ptr(), and libMesh::ParallelObject::processor_id().

Referenced by main(), and ConnectedComponentsTest::testEdge().

866 {
867  LOG_SCOPE("n_connected_components()", "MeshTools");
868 
869  // Yes, I'm being lazy. This is for mesh analysis before a
870  // simulation, not anything going in any loops.
871  if (!mesh.is_serial_on_zero())
872  libmesh_not_implemented();
873 
874  dof_id_type n_components = 0;
875 
876  if (mesh.processor_id())
877  {
878  mesh.comm().broadcast(n_components);
879  return n_components;
880  }
881 
882  // All nodes in a set here are connected (at least indirectly) to
883  // all other nodes in the same set, but have not yet been discovered
884  // to be connected to nodes in other sets.
885  //
886  // Using an unordered_set of ids rather than a set of pointers seems
887  // to be roughly 150% faster?
888  // typedef const Node * node_entry_type
889  typedef dof_id_type node_entry_type;
890  std::vector<std::unordered_set<node_entry_type>> components;
891 
892  // With a typical mesh with few components and somewhat-contiguous
893  // ordering, vector performance should be fine. With a mesh with
894  // many components or completely scrambled ordering, performance
895  // can be a disaster.
896  auto find_component = [&components](node_entry_type n) {
897  for (auto & c: components)
898  if (c.find(n) != c.end())
899  return &c;
900 
901  return (std::unordered_set<node_entry_type> *)(nullptr);
902  };
903 
904  auto add_to_component =
905  [&find_component]
906  (std::unordered_set<node_entry_type> & component, node_entry_type n) {
907  // We may already be in the desired component
908  if (component.find(n) != component.end())
909  return;
910 
911  auto current_component = find_component(n);
912 
913  // Didn't we *just* check this?
914  libmesh_assert (&component != current_component);
915 
916  // If we're unknown, we should be in the desired component
917  if (!current_component)
918  component.insert(n);
919 
920  // If we think we're in another component, it should actually be
921  // part of the desired component
922  else
923  {
924  // Merge the component likely to be smaller into the one
925  // likely to be larger - this is orders of magnitude faster
926  // than the other way around!
927  current_component->merge(component);
928  current_component->swap(component);
929  libmesh_assert(current_component->empty());
930  }
931  };
932 
933  auto & constraint_rows = mesh.get_constraint_rows();
934 
935  for (const auto & elem : mesh.element_ptr_range())
936  {
937  // const node_entry_type first_node = elem->node_ptr(0);
938  const node_entry_type first_node = elem->node_id(0);
939 
940  auto component = find_component(first_node);
941 
942  // If we didn't find one, make a new one, reusing an existing
943  // slot if possible or growing our vector if necessary
944  if (!component)
945  for (auto & c: components)
946  if (c.empty())
947  component = &c;
948 
949  if (!component)
950  component = &components.emplace_back();
951 
952  for (const Node & node : elem->node_ref_range())
953  {
954  // const node_entry_type n = &node;
955  const node_entry_type n = node.id();
956  add_to_component(*component, n);
957 
958  auto it = constraint_rows.find(&node);
959  if (it == constraint_rows.end())
960  continue;
961 
962  for (const auto & [pr, val] : it->second)
963  {
964  // Ignore too-trivial constraint coefficients if
965  // we get a non-default-0 constraint_tol
966  if (std::abs(val) < constraint_tol)
967  continue;
968 
969  const Elem * spline_elem = pr.first;
970  libmesh_assert(spline_elem == mesh.elem_ptr(spline_elem->id()));
971 
972  const Node * spline_node =
973  spline_elem->node_ptr(pr.second);
974 
975  // add_to_component(*component, spline_node);
976  add_to_component(*component, spline_node->id());
977  }
978  }
979  }
980 
981  for (auto & component : components)
982  if (!component.empty())
983  ++n_components;
984 
985  // We calculated this on proc 0; now let everyone else know too
986  mesh.comm().broadcast(n_components);
987 
988  return n_components;
989 }
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1905
A Node is like a Point, but with more information.
Definition: node.h:52
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
virtual bool is_serial_on_zero() const
Definition: mesh_base.h:354
dof_id_type id() const
Definition: dof_object.h:819
libmesh_assert(ctx)
void broadcast(T &data, const unsigned int root_id=0, const bool identical_sizes=false) const
virtual const Elem * elem_ptr(const dof_id_type i) const =0
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2513
processor_id_type processor_id() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ n_elem()

dof_id_type libMesh::MeshTools::n_elem ( const MeshBase::const_element_iterator begin,
const MeshBase::const_element_iterator end 
)

Count up the number of elements of a specific type (as defined by an iterator range).

Definition at line 1004 of file mesh_tools.C.

References distance().

Referenced by libMesh::MeshTools::Subdivision::add_boundary_ghosts(), add_cube_convex_hull_to_mesh(), correct_node_proc_ids(), libMesh::RBEIMEvaluation::get_interior_basis_function_sizes(), main(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::XdrIO::read(), libMesh::STLIO::read_binary(), libMesh::XdrIO::read_header(), libMesh::RBEIMEvaluation::read_in_interior_basis_functions(), libMesh::DynaIO::read_mesh(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::Partitioner::set_node_processor_ids(), libMesh::Partitioner::set_parent_processor_ids(), AllRBBTest::test_cylinder(), AllRBBTest::test_disk(), MeshInputTest::testAbaqusRead(), MeshDeletionsTest::testDeleteElem(), ConnectedComponentsTest::testEdge(), BoundaryInfoTest::testEdgeBoundaryConditions(), LibMeshNetgenTest::testPermutedHole(), libMesh::NetGenMeshInterface::triangulate(), libMesh::XdrIO::write(), libMesh::ExodusII_IO_Helper::write_element_values(), libMesh::UCDIO::write_nodal_data(), libMesh::RBEIMEvaluation::write_out_interior_basis_functions(), libMesh::RBEIMEvaluation::write_out_side_basis_functions(), libMesh::XdrIO::write_serialized_connectivity(), libMesh::System::write_serialized_vector(), and libMesh::System::write_serialized_vectors().

1006 {
1007  return cast_int<dof_id_type>(std::distance(begin, end));
1008 }
Real distance(const Point &p)

◆ n_elem_of_type()

dof_id_type libMesh::MeshTools::n_elem_of_type ( const MeshBase mesh,
const ElemType  type 
)
Returns
The number of elements of type type.

Implemented in terms of type_element_iterators.

Definition at line 735 of file mesh_tools.C.

References distance(), and mesh.

737 {
738  return static_cast<dof_id_type>(std::distance(mesh.type_elements_begin(type),
739  mesh.type_elements_end (type)));
740 }
MeshBase & mesh
Definition: mesh_tools.C:2393
Real distance(const Point &p)
uint8_t dof_id_type
Definition: id_types.h:67

◆ n_levels()

unsigned int libMesh::MeshTools::n_levels ( const MeshBase mesh)
Returns
The number of levels of refinement in the mesh.

Implemented by looping over all the local elements and unpartitioned elements and finding the maximum level, then summing in parallel.

Definition at line 826 of file mesh_tools.C.

References libMesh::as_range(), libMesh::ParallelObject::comm(), TIMPI::Communicator::max(), mesh, n_local_levels(), and paranoid_n_levels().

Referenced by libMesh::BoundaryInfo::_find_id_maps(), libMesh::MeshCommunication::delete_remote_elements(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::PetscDMWrapper::init_dm_data(), libMesh::PetscDMWrapper::init_petscdm(), libMesh::MeshTools::Modification::orient_elements(), libMesh::MeshTools::Modification::permute_elements(), libMesh::Partitioner::set_node_processor_ids(), and libMesh::MeshTools::Modification::smooth().

827 {
828  libmesh_parallel_only(mesh.comm());
829 
830  unsigned int nl = n_local_levels(mesh);
831 
832  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
833  mesh.unpartitioned_elements_end()))
834  nl = std::max(elem->level() + 1, nl);
835 
836  mesh.comm().max(nl);
837 
838  // n_levels() is only valid and should only be called in cases where
839  // the mesh is validly distributed (or serialized). Let's run an
840  // expensive test in debug mode to make sure this is such a case.
841 #ifdef DEBUG
842  const unsigned int paranoid_nl = paranoid_n_levels(mesh);
843  libmesh_assert_equal_to(nl, paranoid_nl);
844 #endif
845  return nl;
846 }
unsigned int n_local_levels(const MeshBase &mesh)
Definition: mesh_tools.C:813
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
unsigned int paranoid_n_levels(const MeshBase &mesh)
Definition: mesh_tools.C:850
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
void max(const T &r, T &o, Request &req) const

◆ n_local_levels()

unsigned int libMesh::MeshTools::n_local_levels ( const MeshBase mesh)
Returns
The number of levels of refinement in the local mesh.

Implemented by looping over all the local elements and finding the maximum level.

Definition at line 813 of file mesh_tools.C.

References libMesh::as_range(), and mesh.

Referenced by n_levels().

814 {
815  unsigned int nl = 0;
816 
817  for (const auto & elem : as_range(mesh.local_elements_begin(),
818  mesh.local_elements_end()))
819  nl = std::max(elem->level() + 1, nl);
820 
821  return nl;
822 }
MeshBase & mesh
Definition: mesh_tools.C:2393
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

◆ n_nodes()

dof_id_type libMesh::MeshTools::n_nodes ( const MeshBase::const_node_iterator begin,
const MeshBase::const_node_iterator end 
)

Count up the number of nodes of a specific type (as defined by an iterator range).

Definition at line 1012 of file mesh_tools.C.

References distance().

Referenced by libmesh_assert_consistent_distributed_nodes(), libmesh_assert_parallel_consistent_new_node_procids(), and libmesh_assert_valid_boundary_ids().

1014 {
1015  return cast_int<dof_id_type>(std::distance(begin, end));
1016 }
Real distance(const Point &p)

◆ n_non_subactive_elem_of_type_at_level()

dof_id_type libMesh::MeshTools::n_non_subactive_elem_of_type_at_level ( const MeshBase mesh,
const ElemType  type,
const unsigned int  level 
)
Returns
The number of elements of type type at the specified refinement level.
Todo:
Replace all of the n_xxx_elem() functions like this with a single function which takes a range of iterators and computes the std::distance between them.

Definition at line 751 of file mesh_tools.C.

References libMesh::as_range(), and mesh.

754 {
755  dof_id_type cnt = 0;
756 
757  // iterate over the elements of the specified type
758  for (const auto & elem : as_range(mesh.type_elements_begin(type),
759  mesh.type_elements_end(type)))
760  if ((elem->level() == level) && !elem->subactive())
761  cnt++;
762 
763  return cnt;
764 }
MeshBase & mesh
Definition: mesh_tools.C:2393
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
uint8_t dof_id_type
Definition: id_types.h:67

◆ n_p_levels()

unsigned int libMesh::MeshTools::n_p_levels ( const MeshBase mesh)
Returns
The number of p-levels of refinement in the mesh.

Implemented by looping over all the local elements and finding the maximum p-level, then summing in parallel.

Definition at line 1049 of file mesh_tools.C.

References libMesh::as_range(), libMesh::ParallelObject::comm(), TIMPI::Communicator::max(), and mesh.

Referenced by libMesh::XdrIO::write().

1050 {
1051  libmesh_parallel_only(mesh.comm());
1052 
1053  unsigned int max_p_level = 0;
1054 
1055  // first my local elements
1056  for (const auto & elem : as_range(mesh.local_elements_begin(),
1057  mesh.local_elements_end()))
1058  max_p_level = std::max(elem->p_level(), max_p_level);
1059 
1060  // then any unpartitioned objects
1061  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
1062  mesh.unpartitioned_elements_end()))
1063  max_p_level = std::max(elem->p_level(), max_p_level);
1064 
1065  mesh.comm().max(max_p_level);
1066  return max_p_level + 1;
1067 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
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
void max(const T &r, T &o, Request &req) const

◆ paranoid_n_levels()

unsigned int libMesh::MeshTools::paranoid_n_levels ( const MeshBase mesh)
Returns
The number of levels of refinement in the mesh, even if that mesh is not currently properly distributed or properly serialized.

Implemented by looping over all elements and finding the maximum level, then summing in parallel. This is much slower than n_levels() but will return correct values even when the mesh is in an inconsistent parallel state.

Definition at line 850 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), TIMPI::Communicator::max(), and mesh.

Referenced by n_levels().

851 {
852  libmesh_parallel_only(mesh.comm());
853 
854  unsigned int nl = 0;
855  for (const auto & elem : mesh.element_ptr_range())
856  nl = std::max(elem->level() + 1, nl);
857 
858  mesh.comm().max(nl);
859  return nl;
860 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
void max(const T &r, T &o, Request &req) const

◆ processor_bounding_sphere()

Sphere libMesh::MeshTools::processor_bounding_sphere ( const MeshBase mesh,
const processor_id_type  pid 
)
Returns
A processor bounding sphere instead of a processor bounding box.

Definition at line 670 of file mesh_tools.C.

References create_processor_bounding_box(), mesh, libMesh::TensorTools::norm(), and libMesh::Real.

672 {
673  libMesh::BoundingBox bbox =
675 
676  const Real diag = (bbox.second - bbox.first).norm();
677  const Point cent = (bbox.second + bbox.first)/2;
678 
679  return Sphere (cent, .5*diag);
680 }
This class defines a sphere.
Definition: sphere.h:72
MeshBase & mesh
Definition: mesh_tools.C:2393
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
auto norm(const T &a)
Definition: tensor_tools.h:74
libMesh::BoundingBox create_processor_bounding_box(const MeshBase &mesh, const processor_id_type pid)
Definition: mesh_tools.C:645
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39

◆ subdomain_bounding_sphere()

Sphere libMesh::MeshTools::subdomain_bounding_sphere ( const MeshBase mesh,
const subdomain_id_type  sid 
)
Returns
A subdomain bounding sphere instead of a subdomain bounding box.

Definition at line 709 of file mesh_tools.C.

References create_subdomain_bounding_box(), mesh, libMesh::TensorTools::norm(), and libMesh::Real.

711 {
712  libMesh::BoundingBox bbox =
714 
715  const Real diag = (bbox.second - bbox.first).norm();
716  const Point cent = (bbox.second + bbox.first)/2;
717 
718  return Sphere (cent, .5*diag);
719 }
This class defines a sphere.
Definition: sphere.h:72
MeshBase & mesh
Definition: mesh_tools.C:2393
libMesh::BoundingBox create_subdomain_bounding_box(const MeshBase &mesh, const subdomain_id_type sid)
Definition: mesh_tools.C:685
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
auto norm(const T &a)
Definition: tensor_tools.h:74
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39

◆ total_weight()

dof_id_type libMesh::MeshTools::total_weight ( const MeshBase mesh)
Returns
The sum over all the elements of the number of nodes per element.

This can be useful for partitioning hybrid meshes. A feasible load balancing scheme is to keep the weight per processor as uniform as possible.

Definition at line 421 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, libMesh::MeshBase::is_serial(), mesh, libMesh::Threads::parallel_reduce(), libMesh::ParallelObject::processor_id(), TIMPI::Communicator::sum(), and weight().

422 {
423  if (!mesh.is_serial())
424  {
425  libmesh_parallel_only(mesh.comm());
427  mesh.comm().sum(weight);
428  dof_id_type unpartitioned_weight =
429  MeshTools::weight (mesh, DofObject::invalid_processor_id);
430  return weight + unpartitioned_weight;
431  }
432 
433  SumElemWeight sew;
434 
435  Threads::parallel_reduce (ConstElemRange (mesh.elements_begin(),
436  mesh.elements_end()),
437  sew);
438  return sew.weight();
439 
440 }
void sum(T &r) const
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2393
virtual bool is_serial() const
Definition: mesh_base.h:347
dof_id_type weight(const MeshBase &mesh, const processor_id_type pid)
Definition: mesh_tools.C:444
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:109
processor_id_type processor_id() const
uint8_t dof_id_type
Definition: id_types.h:67

◆ valid_is_prepared()

bool libMesh::MeshTools::valid_is_prepared ( const MeshBase mesh)

A function for testing whether a mesh's cached is_prepared() setting is not a false positive.

If the mesh is marked as not prepared, or if preparing the already-partitioned mesh (without any repartitioning or renumbering) does not change it, then we return true. If the mesh believes it is prepared but prepare_for_use() would change it, we return false.

Definition at line 1256 of file mesh_tools.C.

References libMesh::MeshBase::clone(), libMesh::MeshBase::is_prepared(), and mesh.

Referenced by ConstraintOperatorTest::test1DCoarseningNewNodes(), ConstraintOperatorTest::test1DCoarseningOperator(), ConstraintOperatorTest::testCoreform(), MeshBaseTest::testMeshBaseVerifyHasCachedElemData(), MeshBaseTest::testMeshBaseVerifyHasNeighborPtrs(), MeshBaseTest::testMeshBaseVerifyIsPrepared(), MeshBaseTest::testMeshBaseVerifyRemovalPreparation(), and libMesh::MeshTetInterface::volume_to_surface_mesh().

1257 {
1258  LOG_SCOPE("valid_is_prepared()", "MeshTools");
1259 
1260  if (!mesh.is_prepared())
1261  return true;
1262 
1263  std::unique_ptr<MeshBase> mesh_clone = mesh.clone();
1264 
1265  // Try preparing (without allowing repartitioning or renumbering, to
1266  // avoid false assertion failures)
1267  bool old_allow_renumbering = mesh_clone->allow_renumbering();
1268  mesh_clone->allow_renumbering(false);
1269 
1270  bool old_skip_partitioning = mesh_clone->skip_partitioning();
1271  mesh_clone->skip_partitioning(true);
1272 
1273  bool old_allow_remote_element_removal = mesh_clone->allow_remote_element_removal();
1274  mesh_clone->allow_remote_element_removal(false);
1275 
1276  // Call prepare_for_use() on the clone
1277  mesh_clone->prepare_for_use();
1278 
1279  // Restore original flag values
1280  mesh_clone->allow_renumbering(old_allow_renumbering);
1281  mesh_clone->skip_partitioning(old_skip_partitioning);
1282  mesh_clone->allow_remote_element_removal(old_allow_remote_element_removal);
1283 
1284  // Check whether the original and clone compare equal
1285  return (mesh == *mesh_clone);
1286 }
bool is_prepared() const
Definition: mesh_base.C:1057
MeshBase & mesh
Definition: mesh_tools.C:2393
virtual std::unique_ptr< MeshBase > clone() const =0
Virtual "copy constructor".

◆ volume()

Real libMesh::MeshTools::volume ( const MeshBase mesh,
unsigned int  dim = libMesh::invalid_uint 
)

Find the total volume of a mesh (interpreting that as area for dim = 2, or total arc length for dim = 1, or number of NodeElem in the mesh for dim = 0).

By default the dimension chosen will be the mesh_dimension(), which if not manually overridden will be the largest dimension of elements in the mesh.

Definition at line 1020 of file mesh_tools.C.

References libMesh::as_range(), libMesh::ParallelObject::comm(), dim, libMesh::invalid_uint, mesh, libMesh::MeshBase::mesh_dimension(), libMesh::ParallelObject::processor_id(), libMesh::Real, and TIMPI::Communicator::sum().

Referenced by libMesh::RBConstruction::add_scaled_matrix_and_vector(), libMesh::MeshBase::get_info(), libMesh::SimplexRefiner::refine_via_edges(), libMesh::SimplexRefiner::should_refine_elem(), AllRBBTest::test_box(), AllRBBTest::test_circle(), AllRBBTest::test_cylinder(), AllRBBTest::test_disk(), AllTriTest::test_helper_c0polyhedron(), AllTriTest::testAllTriC0PolygonOctagon(), MeshTetTest::testHole(), MeshTetTest::testTetInterfaceBase(), and MeshTetTest::testTetsToTets().

1022 {
1023  libmesh_parallel_only(mesh.comm());
1024 
1025  if (dim == libMesh::invalid_uint)
1026  dim = mesh.mesh_dimension();
1027 
1028  Real vol = 0;
1029 
1030  // first my local elements
1031  for (const auto & elem : as_range(mesh.local_elements_begin(),
1032  mesh.local_elements_end()))
1033  if (elem->dim() == dim)
1034  vol += elem->volume();
1035 
1036  // then count any unpartitioned objects, once
1037  if (mesh.processor_id() == 0)
1038  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
1039  mesh.unpartitioned_elements_end()))
1040  if (elem->dim() == dim)
1041  vol += elem->volume();
1042 
1043  mesh.comm().sum(vol);
1044  return vol;
1045 }
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition: libmesh.h:303
unsigned int dim
void sum(T &r) const
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2393
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
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
unsigned int mesh_dimension() const
Definition: mesh_base.C:430
processor_id_type processor_id() const

◆ weight() [1/2]

dof_id_type libMesh::MeshTools::weight ( const MeshBase mesh,
const processor_id_type  pid 
)
Returns
The sum over all the elements on processor pid of nodes per element.

This can be useful for partitioning hybrid meshes. A feasible load balancing scheme is to keep the weight per processor as uniform as possible.

Definition at line 444 of file mesh_tools.C.

References mesh, and libMesh::Threads::parallel_reduce().

Referenced by libMesh::StaticCondensationDofMap::add_uncondensed_dof_plus_constraint_dofs(), assemble_SchroedingerEquation(), assemble_wave(), libMesh::QGrundmann_Moller::gm_rule(), libMesh::QGrid::init_2D(), libMesh::QNodal::init_2D(), libMesh::QGrid::init_3D(), libMesh::QNodal::init_3D(), libMesh::FE< Dim, LAGRANGE_VEC >::init_shape_functions(), libMesh::InfFE< Dim, T_radial, T_map >::init_shape_functions(), libMesh::FEXYZ< Dim >::init_shape_functions(), libMesh::InverseDistanceInterpolation< KDDim >::interpolate(), libMesh::VTKIO::nodes_to_vtk(), libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), CoupledFEMFunctionsx::operator()(), CoupledFEMFunctionsy::operator()(), libMesh::MeshTools::Modification::smooth(), MeshSmootherTest::testVariationalSmoother(), total_weight(), and weight().

445 {
446  SumElemWeight sew;
447 
448  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
449  mesh.pid_elements_end(pid)),
450  sew);
451  return sew.weight();
452 }
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2393
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:109

◆ weight() [2/2]

dof_id_type libMesh::MeshTools::weight ( const MeshBase mesh)
inline

Definition at line 78 of file mesh_tools.h.

References mesh, and weight().

79 { return MeshTools::weight (mesh, mesh.processor_id()); }
dof_id_type weight(const MeshBase &mesh)
Definition: mesh_tools.h:78
MeshBase & mesh