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_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 611 of file mesh_tools.C.

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

612 {
614 
615  const Real diag = (bbox.second - bbox.first).norm();
616  const Point cent = (bbox.second + bbox.first)/2;
617 
618  return Sphere (cent, .5*diag);
619 }
This class defines a sphere.
Definition: sphere.h:72
libMesh::BoundingBox create_bounding_box(const MeshBase &mesh)
Definition: mesh_tools.C:559
MeshBase & mesh
Definition: mesh_tools.C:2278
auto norm(const T &a) -> decltype(std::abs(a))
Definition: tensor_tools.h:74
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
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 449 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(), and libMesh::Tree< N >::Tree().

451 {
452  // A vector indexed over all nodes is too inefficient to use for a
453  // distributed mesh. Use the unordered_map API instead.
454  if (!mesh.is_serial())
455  libmesh_deprecated();
456 
457  nodes_to_elem_map.resize (mesh.max_node_id());
458 
459  for (const auto & elem : mesh.element_ptr_range())
460  for (auto & node : elem->node_ref_range())
461  {
462  libmesh_assert_less (node.id(), nodes_to_elem_map.size());
463  libmesh_assert_less (elem->id(), mesh.n_elem());
464 
465  nodes_to_elem_map[node.id()].push_back(elem->id());
466  }
467 }
MeshBase & mesh
Definition: mesh_tools.C:2278
virtual bool is_serial() const
Definition: mesh_base.h:211
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 471 of file mesh_tools.C.

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

473 {
474  // A vector indexed over all nodes is too inefficient to use for a
475  // distributed mesh. Use the unordered_map API instead.
476  if (!mesh.is_serial())
477  libmesh_deprecated();
478 
479  nodes_to_elem_map.resize (mesh.max_node_id());
480 
481  for (const auto & elem : mesh.element_ptr_range())
482  for (auto & node : elem->node_ref_range())
483  {
484  libmesh_assert_less (node.id(), nodes_to_elem_map.size());
485 
486  nodes_to_elem_map[node.id()].push_back(elem);
487  }
488 }
MeshBase & mesh
Definition: mesh_tools.C:2278
virtual bool is_serial() const
Definition: mesh_base.h:211
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 492 of file mesh_tools.C.

References mesh.

494 {
495  nodes_to_elem_map.clear();
496 
497  for (const auto & elem : mesh.element_ptr_range())
498  for (auto & node : elem->node_ref_range())
499  nodes_to_elem_map[node.id()].push_back(elem->id());
500 }
MeshBase & mesh
Definition: mesh_tools.C:2278

◆ 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 504 of file mesh_tools.C.

References mesh.

506 {
507  nodes_to_elem_map.clear();
508 
509  for (const auto & elem : mesh.element_ptr_range())
510  for (auto & node : elem->node_ref_range())
511  nodes_to_elem_map[node.id()].push_back(elem);
512 }
MeshBase & mesh
Definition: mesh_tools.C:2278

◆ 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 1147 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::clear_spline_nodes(), and libMesh::DynaIO::read_mesh().

1148 {
1149  std::vector<Elem *> nodeelem_to_delete;
1150 
1151  for (auto & elem : mesh.element_ptr_range())
1152  if (elem->type() == NODEELEM &&
1153  elem->mapping_type() == RATIONAL_BERNSTEIN_MAP)
1154  nodeelem_to_delete.push_back(elem);
1155 
1156  auto & constraint_rows = mesh.get_constraint_rows();
1157 
1158  // All our constraint_rows ought to be for spline constraints we're
1159  // about to get rid of.
1160 #ifndef NDEBUG
1161  for (auto & node_row : constraint_rows)
1162  for (auto pr : node_row.second)
1163  {
1164  const Elem * elem = pr.first.first;
1165  libmesh_assert(elem->type() == NODEELEM);
1167  }
1168 #endif
1169 
1170  constraint_rows.clear();
1171 
1172  for (Elem * elem : nodeelem_to_delete)
1173  {
1174  Node * node = elem->node_ptr(0);
1175  mesh.delete_elem(elem);
1176  mesh.delete_node(node);
1177  }
1178 }
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1703
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:2278
virtual void delete_elem(Elem *e)=0
Removes element e from the mesh.
ElemMappingType mapping_type() const
Definition: elem.h:3120
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:2507
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 2393 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().

2394 {
2395  LOG_SCOPE("correct_node_proc_ids()","MeshTools");
2396 
2397  // This function must be run on all processors at once
2398  libmesh_parallel_only(mesh.comm());
2399 
2400  // We require all processors to agree on nodal processor ids before
2401  // going into this algorithm.
2402 #ifdef DEBUG
2404 #endif
2405 
2406  // If we have any unpartitioned elements at this
2407  // stage there is a problem
2408  libmesh_assert (n_elem(mesh.unpartitioned_elements_begin(),
2409  mesh.unpartitioned_elements_end()) == 0);
2410 
2411  // Fix nodes' processor ids. Coarsening may have left us with nodes
2412  // which are no longer touched by any elements of the same processor
2413  // id, and for DofMap to work we need to fix that.
2414 
2415  // This is harder now that libMesh no longer requires a distributed
2416  // mesh to ghost all nodal neighbors: it is possible for two active
2417  // elements on two different processors to share the same node in
2418  // such a way that neither processor knows the others' element
2419  // exists!
2420 
2421  // While we're at it, if this mesh is configured to allow
2422  // repartitioning, we'll repartition *all* the nodes' processor ids
2423  // using the canonical Node heuristic, to try and improve DoF load
2424  // balancing. But if the mesh is disallowing repartitioning, we
2425  // won't touch processor_id on any node where it's valid, regardless
2426  // of whether or not it's canonical.
2427  bool repartition_all_nodes = !mesh.skip_noncritical_partitioning();
2428  std::unordered_set<const Node *> valid_nodes;
2429 
2430  // If we aren't allowed to repartition, then we're going to leave
2431  // every node we can at its current processor_id, and *only*
2432  // repartition the nodes whose current processor id is incompatible
2433  // with DoFMap (because it doesn't touch an active element, e.g. due
2434  // to coarsening)
2435  if (!repartition_all_nodes)
2436  {
2437  for (const auto & elem : mesh.active_element_ptr_range())
2438  for (const auto & node : elem->node_ref_range())
2439  if (elem->processor_id() == node.processor_id())
2440  valid_nodes.insert(&node);
2441 
2442  SyncNodeSet syncv(valid_nodes, mesh);
2443 
2445  (mesh.comm(), mesh.nodes_begin(), mesh.nodes_end(), syncv);
2446  }
2447 
2448  // We build up a set of compatible processor ids for each node
2449  proc_id_map_type new_proc_ids;
2450 
2451  for (auto & elem : mesh.active_element_ptr_range())
2452  {
2453  processor_id_type pid = elem->processor_id();
2454 
2455  for (auto & node : elem->node_ref_range())
2456  {
2457  const dof_id_type id = node.id();
2458  if (auto it = new_proc_ids.find(id);
2459  it == new_proc_ids.end())
2460  new_proc_ids.emplace(id, pid);
2461  else
2462  it->second = node.choose_processor_id(it->second, pid);
2463  }
2464  }
2465 
2466  // Sort the new pids to push to each processor
2467  std::map<processor_id_type, std::vector<std::pair<dof_id_type, processor_id_type>>>
2468  ids_to_push;
2469 
2470  for (const auto & node : mesh.node_ptr_range())
2471  if (const auto it = std::as_const(new_proc_ids).find(node->id());
2472  it != new_proc_ids.end() && node->processor_id() != DofObject::invalid_processor_id)
2473  ids_to_push[node->processor_id()].emplace_back(node->id(), /*pid=*/it->second);
2474 
2475  auto action_functor =
2476  [& mesh, & new_proc_ids]
2478  const std::vector<std::pair<dof_id_type, processor_id_type>> & data)
2479  {
2480  for (const auto & [id, pid] : data)
2481  {
2482  if (const auto it = new_proc_ids.find(id);
2483  it == new_proc_ids.end())
2484  new_proc_ids.emplace(id, pid);
2485  else
2486  {
2487  const Node & node = mesh.node_ref(id);
2488  it->second = node.choose_processor_id(it->second, pid);
2489  }
2490  }
2491  };
2492 
2493  Parallel::push_parallel_vector_data
2494  (mesh.comm(), ids_to_push, action_functor);
2495 
2496  // Now new_proc_ids is correct for every node we used to own. Let's
2497  // ask every other processor about the nodes they used to own. But
2498  // first we'll need to keep track of which nodes we used to own,
2499  // lest we get them confused with nodes we newly own.
2500  std::unordered_set<Node *> ex_local_nodes;
2501  for (auto & node : mesh.local_node_ptr_range())
2502  if (const auto it = new_proc_ids.find(node->id());
2503  it != new_proc_ids.end() && it->second != mesh.processor_id())
2504  ex_local_nodes.insert(node);
2505 
2506  SyncProcIdsFromMap sync(new_proc_ids, mesh);
2507  if (repartition_all_nodes)
2509  (mesh.comm(), mesh.nodes_begin(), mesh.nodes_end(), sync);
2510  else
2511  {
2512  NodesNotInSet nnis(valid_nodes);
2513 
2515  (mesh.comm(), mesh.nodes_begin(), mesh.nodes_end(), nnis, sync);
2516  }
2517 
2518  // And finally let's update the nodes we used to own.
2519  for (const auto & node : ex_local_nodes)
2520  {
2521  if (valid_nodes.count(node))
2522  continue;
2523 
2524  const dof_id_type id = node->id();
2525  const proc_id_map_type::iterator it = new_proc_ids.find(id);
2526  libmesh_assert(it != new_proc_ids.end());
2527  node->processor_id() = it->second;
2528  }
2529 
2530  // We should still have consistent nodal processor ids coming out of
2531  // this algorithm, but if we're allowed to repartition the mesh then
2532  // they should be canonically correct too.
2533 #ifdef DEBUG
2534  libmesh_assert_valid_procids<Node>(mesh);
2535  //if (repartition_all_nodes)
2536  // libmesh_assert_canonical_node_procids(mesh);
2537 #endif
2538 }
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:969
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:1236
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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:2348
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:2103
virtual const Node & node_ref(const dof_id_type i) const
Definition: mesh_base.h:596
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 559 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::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().

560 {
561  // This function must be run on all processors at once
562  libmesh_parallel_only(mesh.comm());
563 
564  FindBBox find_bbox;
565 
566  // Start with any unpartitioned elements we know about locally
567  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(DofObject::invalid_processor_id),
568  mesh.pid_elements_end(DofObject::invalid_processor_id)),
569  find_bbox);
570 
571  // And combine with our local elements
572  find_bbox.bbox().union_with(create_local_bounding_box(mesh));
573 
574  // Compare the bounding boxes across processors
575  mesh.comm().min(find_bbox.min());
576  mesh.comm().max(find_bbox.max());
577 
578  return find_bbox.bbox();
579 }
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:2278
libMesh::BoundingBox create_local_bounding_box(const MeshBase &mesh)
Definition: mesh_tools.C:624
void min(const T &r, T &o, Request &req) const
void max(const T &r, T &o, Request &req) const
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101

◆ 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 624 of file mesh_tools.C.

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

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

625 {
626  FindBBox find_bbox;
627 
628  Threads::parallel_reduce (ConstElemRange (mesh.local_elements_begin(),
629  mesh.local_elements_end()),
630  find_bbox);
631 
632  return find_bbox.bbox();
633 }
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2278
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101

◆ 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 584 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().

585 {
586  // This function must be run on all processors at once
587  libmesh_parallel_only(mesh.comm());
588 
589  FindBBox find_bbox;
590 
591  // Start with any unpartitioned nodes we know about locally
592  Threads::parallel_reduce (ConstNodeRange (mesh.pid_nodes_begin(DofObject::invalid_processor_id),
593  mesh.pid_nodes_end(DofObject::invalid_processor_id)),
594  find_bbox);
595 
596  // Add our local nodes
597  Threads::parallel_reduce (ConstNodeRange (mesh.local_nodes_begin(),
598  mesh.local_nodes_end()),
599  find_bbox);
600 
601  // Compare the bounding boxes across processors
602  mesh.comm().min(find_bbox.min());
603  mesh.comm().max(find_bbox.max());
604 
605  return find_bbox.bbox();
606 }
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:2278
void min(const T &r, T &o, Request &req) const
void max(const T &r, T &o, Request &req) const
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101

◆ 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 638 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().

640 {
641  // This can only be run in parallel, with consistent arguments.
642  libmesh_parallel_only(mesh.comm());
643  libmesh_assert(mesh.comm().verify(pid));
644 
645  libmesh_assert_less (pid, mesh.n_processors());
646 
647  FindBBox find_bbox;
648 
649  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
650  mesh.pid_elements_end(pid)),
651  find_bbox);
652 
653  // Compare the bounding boxes across processors
654  mesh.comm().min(find_bbox.min());
655  mesh.comm().max(find_bbox.max());
656 
657  return find_bbox.bbox();
658 }
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:2278
processor_id_type n_processors() const
void min(const T &r, T &o, Request &req) const
libmesh_assert(ctx)
timpi_pure bool verify(const T &r) const
void max(const T &r, T &o, Request &req) const
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101

◆ 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 678 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().

680 {
681  // This can only be run in parallel, with consistent arguments.
682  libmesh_parallel_only(mesh.comm());
683  libmesh_assert(mesh.comm().verify(sid));
684 
685  FindBBox find_bbox;
686 
688  (ConstElemRange (mesh.active_local_subdomain_elements_begin(sid),
689  mesh.active_local_subdomain_elements_end(sid)),
690  find_bbox);
691 
692  // Compare the bounding boxes across processors
693  mesh.comm().min(find_bbox.min());
694  mesh.comm().max(find_bbox.max());
695 
696  return find_bbox.bbox();
697 }
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:2278
void min(const T &r, T &o, Request &req) const
libmesh_assert(ctx)
timpi_pure bool verify(const T &r) const
void max(const T &r, T &o, Request &req) const
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101

◆ 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 716 of file mesh_tools.C.

References mesh.

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

718 {
719  // Loop over the the elements. If the current element type isn't in
720  // the vector, insert it.
721  for (const auto & elem : mesh.element_ptr_range())
722  if (!std::count(et.begin(), et.end(), elem->type()))
723  et.push_back(elem->type());
724 }
MeshBase & mesh
Definition: mesh_tools.C:2278

◆ 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 537 of file mesh_tools.C.

References mesh.

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

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

◆ 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 517 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().

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

◆ 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 1059 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().

1061 {
1062  // Loop through all the elements
1063  for (auto & elem : mesh.active_local_element_ptr_range())
1064  if (elem->type() == QUAD4)
1065  for (auto s : elem->side_index_range())
1066  {
1067  // Loop over the sides looking for sides that have hanging nodes
1068  // This code is inspired by compute_proj_constraints()
1069  const Elem * neigh = elem->neighbor_ptr(s);
1070 
1071  // If not a boundary side
1072  if (neigh != nullptr)
1073  {
1074  // Is there a coarser element next to this one?
1075  if (neigh->level() < elem->level())
1076  {
1077  const Elem * ancestor = elem;
1078  while (neigh->level() < ancestor->level())
1079  ancestor = ancestor->parent();
1080  unsigned int s_neigh = neigh->which_neighbor_am_i(ancestor);
1081  libmesh_assert_less (s_neigh, neigh->n_neighbors());
1082 
1083  // Couple of helper uints...
1084  unsigned int local_node1=0;
1085  unsigned int local_node2=0;
1086 
1087  bool found_in_neighbor = false;
1088 
1089  // Find the two vertices that make up this side
1090  while (!elem->is_node_on_side(local_node1++,s)) { }
1091  local_node1--;
1092 
1093  // Start looking for the second one with the next node
1094  local_node2=local_node1+1;
1095 
1096  // Find the other one
1097  while (!elem->is_node_on_side(local_node2++,s)) { }
1098  local_node2--;
1099 
1100  //Pull out their global ids:
1101  dof_id_type node1 = elem->node_id(local_node1);
1102  dof_id_type node2 = elem->node_id(local_node2);
1103 
1104  // Now find which node is present in the neighbor
1105  // FIXME This assumes a level one rule!
1106  // The _other_ one is the hanging node
1107 
1108  // First look for the first one
1109  // FIXME could be streamlined a bit
1110  for (unsigned int n=0;n<neigh->n_sides();n++)
1111  if (neigh->node_id(n) == node1)
1112  found_in_neighbor=true;
1113 
1114  dof_id_type hanging_node=0;
1115 
1116  if (!found_in_neighbor)
1117  hanging_node=node1;
1118  else // If it wasn't node1 then it must be node2!
1119  hanging_node=node2;
1120 
1121  // Reset for reuse
1122  local_node1=0;
1123 
1124  // Find the first node that makes up the side in the neighbor (these should be the parent nodes)
1125  while (!neigh->is_node_on_side(local_node1++,s_neigh)) { }
1126  local_node1--;
1127 
1128  local_node2=local_node1+1;
1129 
1130  // Find the second node...
1131  while (!neigh->is_node_on_side(local_node2++,s_neigh)) { }
1132  local_node2--;
1133 
1134  // Save them if we haven't already found the parents for this one
1135  if (hanging_nodes[hanging_node].size()<2)
1136  {
1137  hanging_nodes[hanging_node].push_back(neigh->node_id(local_node1));
1138  hanging_nodes[hanging_node].push_back(neigh->node_id(local_node2));
1139  }
1140  }
1141  }
1142  }
1143 }
const Elem * parent() const
Definition: elem.h:3030
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:2278
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition: elem.h:2919
virtual unsigned int n_sides() const =0
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2598
unsigned int level() const
Definition: elem.h:3074
unsigned int n_neighbors() const
Definition: elem.h:714
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2475
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 1036 of file mesh_tools.C.

References libMesh::DofObject::id().

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

1040 {
1041  find_nodal_neighbors_helper(node.id(), nodes_to_elem_map[node.id()],
1042  neighbors);
1043 }

◆ 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 1047 of file mesh_tools.C.

References libMesh::DofObject::id().

1051 {
1052  const std::vector<const Elem *> node_to_elem_vec =
1053  libmesh_map_find(nodes_to_elem_map, node.id());
1054  find_nodal_neighbors_helper(node.id(), node_to_elem_vec, neighbors);
1055 }

◆ 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 958 of file mesh_tools.C.

References mesh.

960 {
961  for (const auto & elem : mesh.element_ptr_range())
962  if (!elem->subactive())
963  for (auto & n : elem->node_ref_range())
964  not_subactive_node_ids.insert(n.id());
965 }
MeshBase & mesh
Definition: mesh_tools.C:2278

◆ 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 1534 of file mesh_tools.C.

References mesh.

1535 {
1536  for (const auto & elem : mesh.active_element_ptr_range())
1537  for (auto & node : elem->node_ref_range())
1538  libmesh_assert_equal_to
1539  (node.processor_id(),
1540  node.choose_processor_id(node.processor_id(),
1541  elem->processor_id()));
1542 }
MeshBase & mesh
Definition: mesh_tools.C:2278

◆ 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 1642 of file mesh_tools.C.

References libMesh::libmesh_assert(), and mesh.

1643 {
1644  LOG_SCOPE("libmesh_assert_connected_nodes()", "MeshTools");
1645 
1646  std::set<const Node *> used_nodes;
1647 
1648  for (const auto & elem : mesh.element_ptr_range())
1649  {
1650  libmesh_assert (elem);
1651 
1652  for (auto & n : elem->node_ref_range())
1653  used_nodes.insert(&n);
1654  }
1655 
1656  for (const auto & node : mesh.node_ptr_range())
1657  {
1658  libmesh_assert(node);
1659  libmesh_assert(used_nodes.count(node));
1660  }
1661 }
MeshBase & mesh
Definition: mesh_tools.C:2278
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 1954 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().

1955 {
1956  libmesh_parallel_only(mesh.comm());
1957 
1958  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
1959  mesh.comm().max(parallel_max_elem_id);
1960 
1961  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
1962  {
1963  const Elem * elem = mesh.query_elem_ptr(i);
1964  processor_id_type pid =
1965  elem ? elem->processor_id() : DofObject::invalid_processor_id;
1966  mesh.comm().min(pid);
1967  libmesh_assert(elem || pid != mesh.processor_id());
1968  }
1969 
1970  dof_id_type parallel_max_node_id = mesh.max_node_id();
1971  mesh.comm().max(parallel_max_node_id);
1972 
1973  for (dof_id_type i=0; i != parallel_max_node_id; ++i)
1974  {
1975  const Node * node = mesh.query_node_ptr(i);
1976  processor_id_type pid =
1977  node ? node->processor_id() : DofObject::invalid_processor_id;
1978  mesh.comm().min(pid);
1979  libmesh_assert(node || pid != mesh.processor_id());
1980  }
1981 }
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:2278
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:905
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 1984 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().

1985 {
1986  libmesh_parallel_only(mesh.comm());
1987  auto locator = mesh.sub_point_locator();
1988 
1989  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
1990  mesh.comm().max(parallel_max_elem_id);
1991 
1992  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
1993  {
1994  const Elem * elem = mesh.query_elem_ptr(i);
1995 
1996  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
1997  unsigned int n_nodes = my_n_nodes;
1998  mesh.comm().max(n_nodes);
1999 
2000  if (n_nodes)
2001  libmesh_assert(mesh.comm().semiverify(elem ? &my_n_nodes : nullptr));
2002 
2003  for (unsigned int n=0; n != n_nodes; ++n)
2004  {
2005  const Node * node = elem ? elem->node_ptr(n) : nullptr;
2006  processor_id_type pid =
2007  node ? node->processor_id() : DofObject::invalid_processor_id;
2008  mesh.comm().min(pid);
2009  libmesh_assert(node || pid != mesh.processor_id());
2010  }
2011  }
2012 }
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:1638
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:2278
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:2507
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:905
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 1397 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().

1398 {
1399  LOG_SCOPE("libmesh_assert_contiguous_dof_ids()", "MeshTools");
1400 
1401  if (mesh.n_processors() == 1)
1402  return;
1403 
1404  libmesh_parallel_only(mesh.comm());
1405 
1406  dof_id_type min_dof_id = std::numeric_limits<dof_id_type>::max(),
1407  max_dof_id = std::numeric_limits<dof_id_type>::min();
1408 
1409  // Figure out what our local dof id range is
1410  for (const auto * node : mesh.local_node_ptr_range())
1411  {
1412  for (auto v : make_range(node->n_vars(sysnum)))
1413  for (auto c : make_range(node->n_comp(sysnum, v)))
1414  {
1415  dof_id_type id = node->dof_number(sysnum, v, c);
1416  min_dof_id = std::min (min_dof_id, id);
1417  max_dof_id = std::max (max_dof_id, id);
1418  }
1419  }
1420 
1421  // Make sure no other processors' ids are inside it
1422  for (const auto * node : mesh.node_ptr_range())
1423  {
1424  if (node->processor_id() == mesh.processor_id())
1425  continue;
1426  for (auto v : make_range(node->n_vars(sysnum)))
1427  for (auto c : make_range(node->n_comp(sysnum, v)))
1428  {
1429  dof_id_type id = node->dof_number(sysnum, v, c);
1430  libmesh_assert (id < min_dof_id ||
1431  id > max_dof_id);
1432  }
1433  }
1434 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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:140
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 1621 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().

1622 {
1623  LOG_SCOPE("libmesh_assert_equal_connectivity()", "MeshTools");
1624 
1625  dof_id_type pmax_elem_id = mesh.max_elem_id();
1626  mesh.comm().max(pmax_elem_id);
1627 
1628  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1629  {
1630  const Elem * e = mesh.query_elem_ptr(i);
1631 
1632  std::vector<dof_id_type> nodes;
1633  if (e)
1634  for (auto n : e->node_index_range())
1635  nodes.push_back(e->node_id(n));
1636 
1637  libmesh_assert(mesh.comm().semiverify(e ? &nodes : nullptr));
1638  }
1639 }
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:2278
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:2683
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2475
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 1212 of file mesh_tools.C.

References libMesh::invalid_uint, and mesh.

1213 {
1214  LOG_SCOPE("libmesh_assert_equal_n_systems()", "MeshTools");
1215 
1216  unsigned int n_sys = libMesh::invalid_uint;
1217 
1218  for (const auto & elem : mesh.element_ptr_range())
1219  {
1220  if (n_sys == libMesh::invalid_uint)
1221  n_sys = elem->n_systems();
1222  else
1223  libmesh_assert_equal_to (elem->n_systems(), n_sys);
1224  }
1225 
1226  for (const auto & node : mesh.node_ptr_range())
1227  {
1228  if (n_sys == libMesh::invalid_uint)
1229  n_sys = node->n_systems();
1230  else
1231  libmesh_assert_equal_to (node->n_systems(), n_sys);
1232  }
1233 }
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:310
MeshBase & mesh
Definition: mesh_tools.C:2278

◆ 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 1605 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().

1606 {
1607  LOG_SCOPE("libmesh_assert_equal_points()", "MeshTools");
1608 
1609  dof_id_type pmax_node_id = mesh.max_node_id();
1610  mesh.comm().max(pmax_node_id);
1611 
1612  for (dof_id_type i=0; i != pmax_node_id; ++i)
1613  {
1614  const Point * p = mesh.query_node_ptr(i);
1615 
1617  }
1618 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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 1586 of file mesh_tools.C.

References libMesh::libmesh_assert(), and mesh.

1588 {
1589  for (const auto & elem : mesh.element_ptr_range())
1590  {
1591  libmesh_assert (elem);
1592  libmesh_assert_not_equal_to (elem->parent(), bad_elem);
1593  for (auto n : elem->neighbor_ptr_range())
1594  libmesh_assert_not_equal_to (n, bad_elem);
1595 
1596 #ifdef LIBMESH_ENABLE_AMR
1597  if (elem->has_children())
1598  for (auto & child : elem->child_ref_range())
1599  libmesh_assert_not_equal_to (&child, bad_elem);
1600 #endif
1601  }
1602 }
MeshBase & mesh
Definition: mesh_tools.C:2278
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 1238 of file mesh_tools.C.

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

1239 {
1240  LOG_SCOPE("libmesh_assert_old_dof_objects()", "MeshTools");
1241 
1242  for (const auto & elem : mesh.element_ptr_range())
1243  {
1244  if (elem->refinement_flag() == Elem::JUST_REFINED ||
1245  elem->refinement_flag() == Elem::INACTIVE)
1246  continue;
1247 
1248  if (elem->has_dofs())
1249  libmesh_assert(elem->get_old_dof_object());
1250 
1251  for (auto & node : elem->node_ref_range())
1252  if (node.has_dofs())
1253  libmesh_assert(node.get_old_dof_object());
1254  }
1255 }
MeshBase & mesh
Definition: mesh_tools.C:2278
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 2065 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().

2066 {
2067  LOG_SCOPE("libmesh_assert_parallel_consistent_new_node_procids()", "MeshTools");
2068 
2069  if (mesh.n_processors() == 1)
2070  return;
2071 
2072  libmesh_parallel_only(mesh.comm());
2073 
2074  // We want this test to hit every node when called even after nodes
2075  // have been added asynchronously but before everything has been
2076  // renumbered.
2077  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
2078  mesh.comm().max(parallel_max_elem_id);
2079 
2080  std::vector<bool> elem_touched_by_anyone(parallel_max_elem_id, false);
2081 
2082  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2083  {
2084  const Elem * elem = mesh.query_elem_ptr(i);
2085 
2086  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
2087  unsigned int n_nodes = my_n_nodes;
2088  mesh.comm().max(n_nodes);
2089 
2090  if (n_nodes)
2091  libmesh_assert(mesh.comm().semiverify(elem ? &my_n_nodes : nullptr));
2092 
2093  for (unsigned int n=0; n != n_nodes; ++n)
2094  {
2095  const Node * node = elem ? elem->node_ptr(n) : nullptr;
2096  const processor_id_type pid = node ? node->processor_id() : 0;
2097  libmesh_assert(mesh.comm().semiverify (node ? &pid : nullptr));
2098  }
2099  }
2100 }
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:2278
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:2507
processor_id_type processor_id() const
Definition: dof_object.h:905
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 2017 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().

2018 {
2019  LOG_SCOPE("libmesh_assert_parallel_consistent_procids()", "MeshTools");
2020 
2021  if (mesh.n_processors() == 1)
2022  return;
2023 
2024  libmesh_parallel_only(mesh.comm());
2025 
2026  // Some code (looking at you, stitch_meshes) modifies DofObject ids
2027  // without keeping max_elem_id()/max_node_id() consistent, but
2028  // that's done in a safe way for performance reasons, so we'll play
2029  // along and just figure out new max ids ourselves.
2030  dof_id_type parallel_max_elem_id = 0;
2031  for (const auto & elem : mesh.element_ptr_range())
2032  parallel_max_elem_id = std::max<dof_id_type>(parallel_max_elem_id,
2033  elem->id()+1);
2034  mesh.comm().max(parallel_max_elem_id);
2035 
2036  // Check processor ids for consistency between processors
2037 
2038  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2039  {
2040  const Elem * elem = mesh.query_elem_ptr(i);
2041 
2042  processor_id_type min_id =
2043  elem ? elem->processor_id() :
2044  std::numeric_limits<processor_id_type>::max();
2045  mesh.comm().min(min_id);
2046 
2047  processor_id_type max_id =
2048  elem ? elem->processor_id() :
2049  std::numeric_limits<processor_id_type>::min();
2050  mesh.comm().max(max_id);
2051 
2052  if (elem)
2053  {
2054  libmesh_assert_equal_to (min_id, elem->processor_id());
2055  libmesh_assert_equal_to (max_id, elem->processor_id());
2056  }
2057 
2058  if (min_id == mesh.processor_id())
2059  libmesh_assert(elem);
2060  }
2061 }
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:2278
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:905
uint8_t dof_id_type
Definition: id_types.h:67

◆ libmesh_assert_parallel_consistent_procids< Node >()

Definition at line 2103 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 correct_node_proc_ids(), and libMesh::MeshCommunication::make_new_node_proc_ids_parallel_consistent().

2104 {
2105  LOG_SCOPE("libmesh_assert_parallel_consistent_procids()", "MeshTools");
2106 
2107  if (mesh.n_processors() == 1)
2108  return;
2109 
2110  libmesh_parallel_only(mesh.comm());
2111 
2112  // We want this test to be valid even when called even after nodes
2113  // have been added asynchronously but before they're renumbered
2114  //
2115  // Plus, some code (looking at you, stitch_meshes) modifies
2116  // DofObject ids without keeping max_elem_id()/max_node_id()
2117  // consistent, but that's done in a safe way for performance
2118  // reasons, so we'll play along and just figure out new max ids
2119  // ourselves.
2120  dof_id_type parallel_max_node_id = 0;
2121  for (const auto & node : mesh.node_ptr_range())
2122  parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
2123  node->id()+1);
2124  mesh.comm().max(parallel_max_node_id);
2125 
2126  std::vector<bool> node_touched_by_anyone(parallel_max_node_id, false);
2127 
2128  for (const auto & elem : as_range(mesh.local_elements_begin(),
2129  mesh.local_elements_end()))
2130  {
2131  libmesh_assert (elem);
2132 
2133  for (auto & node : elem->node_ref_range())
2134  {
2135  dof_id_type nodeid = node.id();
2136  node_touched_by_anyone[nodeid] = true;
2137  }
2138  }
2139  mesh.comm().max(node_touched_by_anyone);
2140 
2141  // Check processor ids for consistency between processors
2142  // on any node an element touches
2143  for (dof_id_type i=0; i != parallel_max_node_id; ++i)
2144  {
2145  if (!node_touched_by_anyone[i])
2146  continue;
2147 
2148  const Node * node = mesh.query_node_ptr(i);
2149  const processor_id_type pid = node ? node->processor_id() : 0;
2150 
2151  libmesh_assert(mesh.comm().semiverify (node ? &pid : nullptr));
2152  }
2153 }
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:2278
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:905
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 1439 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.

1440 {
1441  LOG_SCOPE("libmesh_assert_topology_consistent_procids()", "MeshTools");
1442 
1443  // This parameter is not used when !LIBMESH_ENABLE_AMR
1445 
1446  // If we're adaptively refining, check processor ids for consistency
1447  // between parents and children.
1448 #ifdef LIBMESH_ENABLE_AMR
1449 
1450  // Ancestor elements we won't worry about, but subactive and active
1451  // elements ought to have parents with consistent processor ids
1452  for (const auto & elem : mesh.element_ptr_range())
1453  {
1454  libmesh_assert(elem);
1455 
1456  if (!elem->active() && !elem->subactive())
1457  continue;
1458 
1459  const Elem * parent = elem->parent();
1460 
1461  if (parent)
1462  {
1463  libmesh_assert(parent->has_children());
1464  processor_id_type parent_procid = parent->processor_id();
1465  bool matching_child_id = false;
1466  // If we've got a remote_elem then we don't know whether
1467  // it's responsible for the parent's processor id; all
1468  // we can do is assume it is and let its processor fail
1469  // an assert if there's something wrong.
1470  for (auto & child : parent->child_ref_range())
1471  if (&child == remote_elem ||
1472  child.processor_id() == parent_procid)
1473  matching_child_id = true;
1474  libmesh_assert(matching_child_id);
1475  }
1476  }
1477 #endif
1478 }
const Elem * parent() const
Definition: elem.h:3030
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2278
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:2346
uint8_t processor_id_type
void libmesh_ignore(const Args &...)
libmesh_assert(ctx)
processor_id_type processor_id() const
Definition: dof_object.h:905
bool has_children() const
Definition: elem.h:2979
const RemoteElem * remote_elem
Definition: remote_elem.C:57

◆ libmesh_assert_topology_consistent_procids< Node >()

Definition at line 1483 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().

1484 {
1485  LOG_SCOPE("libmesh_assert_topology_consistent_procids()", "MeshTools");
1486 
1487  if (mesh.n_processors() == 1)
1488  return;
1489 
1490  libmesh_parallel_only(mesh.comm());
1491 
1492  // We want this test to be valid even when called after nodes have
1493  // been added asynchronously but before they're renumbered.
1494  //
1495  // Plus, some code (looking at you, stitch_meshes) modifies
1496  // DofObject ids without keeping max_elem_id()/max_node_id()
1497  // consistent, but that's done in a safe way for performance
1498  // reasons, so we'll play along and just figure out new max ids
1499  // ourselves.
1500  dof_id_type parallel_max_node_id = 0;
1501  for (const auto & node : mesh.node_ptr_range())
1502  parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
1503  node->id()+1);
1504  mesh.comm().max(parallel_max_node_id);
1505 
1506 
1507  std::vector<bool> node_touched_by_me(parallel_max_node_id, false);
1508 
1509  for (const auto & elem : as_range(mesh.local_elements_begin(),
1510  mesh.local_elements_end()))
1511  {
1512  libmesh_assert (elem);
1513 
1514  for (auto & node : elem->node_ref_range())
1515  {
1516  dof_id_type nodeid = node.id();
1517  node_touched_by_me[nodeid] = true;
1518  }
1519  }
1520  std::vector<bool> node_touched_by_anyone(node_touched_by_me);
1521  mesh.comm().max(node_touched_by_anyone);
1522 
1523  for (const auto & node : mesh.local_node_ptr_range())
1524  {
1525  libmesh_assert(node);
1526  dof_id_type nodeid = node->id();
1527  libmesh_assert(!node_touched_by_anyone[nodeid] ||
1528  node_touched_by_me[nodeid]);
1529  }
1530 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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 1341 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().

1342 {
1343  LOG_SCOPE("libmesh_assert_valid_amr_elem_ids()", "MeshTools");
1344 
1345  for (const auto & elem : mesh.element_ptr_range())
1346  {
1347  libmesh_assert (elem);
1348 
1349  const Elem * parent = elem->parent();
1350 
1351  if (parent)
1352  {
1353  libmesh_assert_greater_equal (elem->id(), parent->id());
1354  libmesh_assert_greater_equal (elem->processor_id(), parent->processor_id());
1355  }
1356  }
1357 }
const Elem * parent() const
Definition: elem.h:3030
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2278
dof_id_type id() const
Definition: dof_object.h:828
libmesh_assert(ctx)
processor_id_type processor_id() const
Definition: dof_object.h:905

◆ 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 1361 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().

1362 {
1363  LOG_SCOPE("libmesh_assert_valid_amr_interior_parents()", "MeshTools");
1364 
1365  for (const auto & elem : mesh.element_ptr_range())
1366  {
1367  libmesh_assert (elem);
1368 
1369  // We can skip to the next element if we're full-dimension
1370  // and therefore don't have any interior parents
1371  if (elem->dim() >= LIBMESH_DIM)
1372  continue;
1373 
1374  const Elem * ip = elem->interior_parent();
1375 
1376  const Elem * parent = elem->parent();
1377 
1378  if (ip && (ip != remote_elem) && parent)
1379  {
1380  libmesh_assert_equal_to (ip->top_parent(),
1381  elem->top_parent()->interior_parent());
1382 
1383  if (ip->level() == elem->level())
1384  libmesh_assert_equal_to (ip->parent(),
1385  parent->interior_parent());
1386  else
1387  {
1388  libmesh_assert_less (ip->level(), elem->level());
1389  libmesh_assert_equal_to (ip, parent->interior_parent());
1390  }
1391  }
1392  }
1393 }
const Elem * parent() const
Definition: elem.h:3030
const Elem * interior_parent() const
Definition: elem.C:1186
const Elem * top_parent() const
Definition: elem.h:3056
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2278
libmesh_assert(ctx)
unsigned int level() const
Definition: elem.h:3074
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 1708 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::DofMap::create_dof_constraints(), and libMesh::MeshBase::prepare_for_use().

1709 {
1710  LOG_SCOPE("libmesh_assert_valid_boundary_ids()", "MeshTools");
1711 
1712  if (mesh.n_processors() == 1)
1713  return;
1714 
1715  libmesh_parallel_only(mesh.comm());
1716 
1717  const BoundaryInfo & boundary_info = mesh.get_boundary_info();
1718 
1719  dof_id_type pmax_elem_id = mesh.max_elem_id();
1720  mesh.comm().max(pmax_elem_id);
1721 
1722  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1723  {
1724  const Elem * elem = mesh.query_elem_ptr(i);
1725  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
1726  const unsigned int my_n_edges = elem ? elem->n_edges() : 0;
1727  const unsigned int my_n_sides = elem ? elem->n_sides() : 0;
1728  unsigned int
1729  n_nodes = my_n_nodes,
1730  n_edges = my_n_edges,
1731  n_sides = my_n_sides;
1732 
1733  mesh.comm().max(n_nodes);
1734  mesh.comm().max(n_edges);
1735  mesh.comm().max(n_sides);
1736 
1737  if (elem)
1738  {
1739  libmesh_assert_equal_to(my_n_nodes, n_nodes);
1740  libmesh_assert_equal_to(my_n_edges, n_edges);
1741  libmesh_assert_equal_to(my_n_sides, n_sides);
1742  }
1743 
1744  // Let's test all IDs on the element with one communication
1745  // rather than n_nodes + n_edges + n_sides communications, to
1746  // cut down on latency in dbg modes.
1747  std::vector<boundary_id_type> all_bcids;
1748 
1749  for (unsigned int n=0; n != n_nodes; ++n)
1750  {
1751  std::vector<boundary_id_type> bcids;
1752  if (elem)
1753  {
1754  boundary_info.boundary_ids(elem->node_ptr(n), bcids);
1755 
1756  // Ordering of boundary ids shouldn't matter
1757  std::sort(bcids.begin(), bcids.end());
1758  }
1759  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1760 
1761  all_bcids.insert(all_bcids.end(), bcids.begin(),
1762  bcids.end());
1763  // Separator
1764  all_bcids.push_back(BoundaryInfo::invalid_id);
1765  }
1766 
1767  for (unsigned short e=0; e != n_edges; ++e)
1768  {
1769  std::vector<boundary_id_type> bcids;
1770 
1771  if (elem)
1772  {
1773  boundary_info.edge_boundary_ids(elem, e, bcids);
1774 
1775  // Ordering of boundary ids shouldn't matter
1776  std::sort(bcids.begin(), bcids.end());
1777  }
1778 
1779  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1780 
1781  all_bcids.insert(all_bcids.end(), bcids.begin(),
1782  bcids.end());
1783  // Separator
1784  all_bcids.push_back(BoundaryInfo::invalid_id);
1785 
1786  if (elem)
1787  {
1788  boundary_info.raw_edge_boundary_ids(elem, e, bcids);
1789 
1790  // Ordering of boundary ids shouldn't matter
1791  std::sort(bcids.begin(), bcids.end());
1792 
1793  all_bcids.insert(all_bcids.end(), bcids.begin(),
1794  bcids.end());
1795  // Separator
1796  all_bcids.push_back(BoundaryInfo::invalid_id);
1797  }
1798 
1799  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1800  }
1801 
1802  for (unsigned short s=0; s != n_sides; ++s)
1803  {
1804  std::vector<boundary_id_type> bcids;
1805 
1806  if (elem)
1807  {
1808  boundary_info.boundary_ids(elem, s, bcids);
1809 
1810  // Ordering of boundary ids shouldn't matter
1811  std::sort(bcids.begin(), bcids.end());
1812 
1813  all_bcids.insert(all_bcids.end(), bcids.begin(),
1814  bcids.end());
1815  // Separator
1816  all_bcids.push_back(BoundaryInfo::invalid_id);
1817  }
1818 
1819  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1820 
1821  if (elem)
1822  {
1823  boundary_info.raw_boundary_ids(elem, s, bcids);
1824 
1825  // Ordering of boundary ids shouldn't matter
1826  std::sort(bcids.begin(), bcids.end());
1827 
1828  all_bcids.insert(all_bcids.end(), bcids.begin(),
1829  bcids.end());
1830  // Separator
1831  all_bcids.push_back(BoundaryInfo::invalid_id);
1832  }
1833 
1834  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1835  }
1836 
1837  for (unsigned short sf=0; sf != 2; ++sf)
1838  {
1839  std::vector<boundary_id_type> bcids;
1840 
1841  if (elem)
1842  {
1843  boundary_info.shellface_boundary_ids(elem, sf, bcids);
1844 
1845  // Ordering of boundary ids shouldn't matter
1846  std::sort(bcids.begin(), bcids.end());
1847 
1848  all_bcids.insert(all_bcids.end(), bcids.begin(),
1849  bcids.end());
1850  // Separator
1851  all_bcids.push_back(BoundaryInfo::invalid_id);
1852  }
1853 
1854  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1855 
1856  if (elem)
1857  {
1858  boundary_info.raw_shellface_boundary_ids(elem, sf, bcids);
1859 
1860  // Ordering of boundary ids shouldn't matter
1861  std::sort(bcids.begin(), bcids.end());
1862 
1863  all_bcids.insert(all_bcids.end(), bcids.begin(),
1864  bcids.end());
1865  // Separator
1866  all_bcids.push_back(BoundaryInfo::invalid_id);
1867  }
1868 
1869  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1870  }
1871 
1873  (elem ? &all_bcids : nullptr));
1874  }
1875 }
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:2278
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:165
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:2507
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 1665 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::MeshCommunication::delete_remote_elements(), and libMesh::MeshBase::prepare_for_use().

1666 {
1667  libmesh_parallel_only(mesh.comm());
1668 
1669  const auto & constraint_rows = mesh.get_constraint_rows();
1670 
1671  bool have_constraint_rows = !constraint_rows.empty();
1672  mesh.comm().max(have_constraint_rows);
1673  if (!have_constraint_rows)
1674  return;
1675 
1676  for (auto & row : constraint_rows)
1677  {
1678  const Node * node = row.first;
1679  libmesh_assert(node == mesh.node_ptr(node->id()));
1680 
1681  for (auto & pr : row.second)
1682  {
1683  const Elem * spline_elem = pr.first.first;
1684  libmesh_assert(spline_elem == mesh.elem_ptr(spline_elem->id()));
1685  }
1686  }
1687 
1688  dof_id_type pmax_node_id = mesh.max_node_id();
1689  mesh.comm().max(pmax_node_id);
1690 
1691  for (dof_id_type i=0; i != pmax_node_id; ++i)
1692  {
1693  const Node * node = mesh.query_node_ptr(i);
1694 
1695  bool have_constraint = constraint_rows.count(node);
1696 
1697  const std::size_t my_n_constraints = have_constraint ?
1698  libmesh_map_find(constraint_rows, node).size() : std::size_t(-1);
1699  const std::size_t * n_constraints = node ?
1700  &my_n_constraints : nullptr;
1701 
1702  libmesh_assert(mesh.comm().semiverify(n_constraints));
1703  }
1704 }
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1703
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:2278
dof_id_type id() const
Definition: dof_object.h:828
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 1878 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().

1879 {
1880  LOG_SCOPE("libmesh_assert_valid_dof_ids()", "MeshTools");
1881 
1882  if (mesh.n_processors() == 1)
1883  return;
1884 
1885  libmesh_parallel_only(mesh.comm());
1886 
1887  dof_id_type pmax_elem_id = mesh.max_elem_id();
1888  mesh.comm().max(pmax_elem_id);
1889 
1890  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1891  assert_semiverify_dofobj(mesh.comm(),
1892  mesh.query_elem_ptr(i),
1893  sysnum);
1894 
1895  dof_id_type pmax_node_id = mesh.max_node_id();
1896  mesh.comm().max(pmax_node_id);
1897 
1898  for (dof_id_type i=0; i != pmax_node_id; ++i)
1899  assert_semiverify_dofobj(mesh.comm(),
1900  mesh.query_node_ptr(i),
1901  sysnum);
1902 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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 1318 of file mesh_tools.C.

References libMesh::libmesh_assert(), and mesh.

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

1319 {
1320  LOG_SCOPE("libmesh_assert_valid_elem_ids()", "MeshTools");
1321 
1322  processor_id_type lastprocid = 0;
1323  dof_id_type lastelemid = 0;
1324 
1325  for (const auto & elem : mesh.active_element_ptr_range())
1326  {
1327  libmesh_assert (elem);
1328  processor_id_type elemprocid = elem->processor_id();
1329  dof_id_type elemid = elem->id();
1330 
1331  libmesh_assert_greater_equal (elemid, lastelemid);
1332  libmesh_assert_greater_equal (elemprocid, lastprocid);
1333 
1334  lastelemid = elemid;
1335  lastprocid = elemprocid;
1336  }
1337 }
MeshBase & mesh
Definition: mesh_tools.C:2278
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 2205 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().

2207 {
2208  LOG_SCOPE("libmesh_assert_valid_neighbors()", "MeshTools");
2209 
2210  for (const auto & elem : mesh.element_ptr_range())
2211  {
2212  libmesh_assert (elem);
2213  elem->libmesh_assert_valid_neighbors();
2214  }
2215 
2216  if (mesh.n_processors() == 1)
2217  return;
2218 
2219  libmesh_parallel_only(mesh.comm());
2220 
2221  dof_id_type pmax_elem_id = mesh.max_elem_id();
2222  mesh.comm().max(pmax_elem_id);
2223 
2224  for (dof_id_type i=0; i != pmax_elem_id; ++i)
2225  {
2226  const Elem * elem = mesh.query_elem_ptr(i);
2227 
2228  const unsigned int my_n_neigh = elem ? elem->n_neighbors() : 0;
2229  unsigned int n_neigh = my_n_neigh;
2230  mesh.comm().max(n_neigh);
2231  if (elem)
2232  libmesh_assert_equal_to (my_n_neigh, n_neigh);
2233 
2234  for (unsigned int n = 0; n != n_neigh; ++n)
2235  {
2236  dof_id_type my_neighbor = DofObject::invalid_id;
2237  dof_id_type * p_my_neighbor = nullptr;
2238 
2239  // If we have a non-remote_elem neighbor link, then we can
2240  // verify it.
2241  if (elem && elem->neighbor_ptr(n) != remote_elem)
2242  {
2243  p_my_neighbor = &my_neighbor;
2244  if (elem->neighbor_ptr(n))
2245  my_neighbor = elem->neighbor_ptr(n)->id();
2246 
2247  // But wait - if we haven't set remote_elem links yet then
2248  // some nullptr links on ghost elements might be
2249  // future-remote_elem links, so we can't verify those.
2250  if (!assert_valid_remote_elems &&
2251  !elem->neighbor_ptr(n) &&
2252  elem->processor_id() != mesh.processor_id())
2253  p_my_neighbor = nullptr;
2254  }
2255  libmesh_assert(mesh.comm().semiverify(p_my_neighbor));
2256  }
2257  }
2258 }
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:2278
processor_id_type n_processors() const
dof_id_type id() const
Definition: dof_object.h:828
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:2598
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:714
processor_id_type processor_id() const
processor_id_type processor_id() const
Definition: dof_object.h:905
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 1262 of file mesh_tools.C.

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

1263 {
1264  LOG_SCOPE("libmesh_assert_valid_node_pointers()", "MeshTools");
1265 
1266  // Here we specifically do not want "auto &" because we need to
1267  // reseat the (temporary) pointer variable in the loop below,
1268  // without modifying the original.
1269  for (const Elem * elem : mesh.element_ptr_range())
1270  {
1271  libmesh_assert (elem);
1272  while (elem)
1273  {
1274  elem->libmesh_assert_valid_node_pointers();
1275  for (auto n : elem->neighbor_ptr_range())
1276  if (n && n != remote_elem)
1277  n->libmesh_assert_valid_node_pointers();
1278 
1279  libmesh_assert_not_equal_to (elem->parent(), remote_elem);
1280  elem = elem->parent();
1281  }
1282  }
1283 }
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2278
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 588 of file mesh_tools.h.

References mesh.

589 {
590  libmesh_assert_parallel_consistent_procids<DofObjectSubclass>(mesh);
591  libmesh_assert_topology_consistent_procids<DofObjectSubclass>(mesh);
592 }
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 2158 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().

2159 {
2160  LOG_SCOPE("libmesh_assert_valid_refinement_flags()", "MeshTools");
2161 
2162  libmesh_parallel_only(mesh.comm());
2163  if (mesh.n_processors() == 1)
2164  return;
2165 
2166  dof_id_type pmax_elem_id = mesh.max_elem_id();
2167  mesh.comm().max(pmax_elem_id);
2168 
2169  std::vector<unsigned char> my_elem_h_state(pmax_elem_id, 255);
2170  std::vector<unsigned char> my_elem_p_state(pmax_elem_id, 255);
2171 
2172  for (const auto & elem : mesh.element_ptr_range())
2173  {
2174  libmesh_assert (elem);
2175  dof_id_type elemid = elem->id();
2176 
2177  my_elem_h_state[elemid] =
2178  static_cast<unsigned char>(elem->refinement_flag());
2179 
2180  my_elem_p_state[elemid] =
2181  static_cast<unsigned char>(elem->p_refinement_flag());
2182  }
2183  std::vector<unsigned char> min_elem_h_state(my_elem_h_state);
2184  mesh.comm().min(min_elem_h_state);
2185 
2186  std::vector<unsigned char> min_elem_p_state(my_elem_p_state);
2187  mesh.comm().min(min_elem_p_state);
2188 
2189  for (dof_id_type i=0; i!= pmax_elem_id; ++i)
2190  {
2191  libmesh_assert(my_elem_h_state[i] == 255 ||
2192  my_elem_h_state[i] == min_elem_h_state[i]);
2193  libmesh_assert(my_elem_p_state[i] == 255 ||
2194  my_elem_p_state[i] == min_elem_p_state[i]);
2195  }
2196 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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 1547 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().

1548 {
1549  LOG_SCOPE("libmesh_assert_valid_refinement_tree()", "MeshTools");
1550 
1551  for (const auto & elem : mesh.element_ptr_range())
1552  {
1553  libmesh_assert(elem);
1554  if (elem->has_children())
1555  for (auto & child : elem->child_ref_range())
1556  if (&child != remote_elem)
1557  libmesh_assert_equal_to (child.parent(), elem);
1558  if (elem->active())
1559  {
1560  libmesh_assert(!elem->ancestor());
1561  libmesh_assert(!elem->subactive());
1562  }
1563  else if (elem->ancestor())
1564  {
1565  libmesh_assert(!elem->subactive());
1566  }
1567  else
1568  libmesh_assert(elem->subactive());
1569 
1570  if (elem->p_refinement_flag() == Elem::JUST_REFINED)
1571  libmesh_assert_greater(elem->p_level(), 0);
1572  }
1573 }
MeshBase & mesh
Definition: mesh_tools.C:2278
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 1287 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().

1288 {
1289  LOG_SCOPE("libmesh_assert_valid_remote_elems()", "MeshTools");
1290 
1291  for (const auto & elem : as_range(mesh.local_elements_begin(),
1292  mesh.local_elements_end()))
1293  {
1294  libmesh_assert (elem);
1295 
1296  // We currently don't allow active_local_elements to have
1297  // remote_elem neighbors
1298  if (elem->active())
1299  for (auto n : elem->neighbor_ptr_range())
1300  libmesh_assert_not_equal_to (n, remote_elem);
1301 
1302 #ifdef LIBMESH_ENABLE_AMR
1303  const Elem * parent = elem->parent();
1304  if (parent)
1305  libmesh_assert_not_equal_to (parent, remote_elem);
1306 
1307  // We can only be strict about active elements' subactive
1308  // children
1309  if (elem->active() && elem->has_children())
1310  for (auto & child : elem->child_ref_range())
1311  libmesh_assert_not_equal_to (&child, remote_elem);
1312 #endif
1313  }
1314 }
const Elem * parent() const
Definition: elem.h:3030
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2278
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.

FIXME: we ought to check for uniqueness too.

Definition at line 1906 of file mesh_tools.C.

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), 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::prepare_for_use(), and libMesh::SimplexRefiner::refine_via_edges().

1907 {
1908  LOG_SCOPE("libmesh_assert_valid_unique_ids()", "MeshTools");
1909 
1910  libmesh_parallel_only(mesh.comm());
1911 
1912  // First collect all the unique_ids we can see and make sure there's
1913  // no duplicates
1914  std::unordered_set<unique_id_type> semilocal_unique_ids;
1915 
1916  for (auto const & elem : mesh.active_element_ptr_range())
1917  {
1918  libmesh_assert (!semilocal_unique_ids.count(elem->unique_id()));
1919  semilocal_unique_ids.insert(elem->unique_id());
1920  }
1921 
1922  for (auto const & node : mesh.node_ptr_range())
1923  {
1924  libmesh_assert (!semilocal_unique_ids.count(node->unique_id()));
1925  semilocal_unique_ids.insert(node->unique_id());
1926  }
1927 
1928  // Then make sure elements are all in sync and remote elements don't
1929  // duplicate semilocal
1930 
1931  dof_id_type pmax_elem_id = mesh.max_elem_id();
1932  mesh.comm().max(pmax_elem_id);
1933 
1934  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1935  {
1936  const Elem * elem = mesh.query_elem_ptr(i);
1937  assert_dofobj_unique_id(mesh.comm(), elem, semilocal_unique_ids);
1938  }
1939 
1940  // Then make sure nodes are all in sync and remote elements don't
1941  // duplicate semilocal
1942 
1943  dof_id_type pmax_node_id = mesh.max_node_id();
1944  mesh.comm().max(pmax_node_id);
1945 
1946  for (dof_id_type i=0; i != pmax_node_id; ++i)
1947  {
1948  const Node * node = mesh.query_node_ptr(i);
1949  assert_dofobj_unique_id(mesh.comm(), node, semilocal_unique_ids);
1950  }
1951 }
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:2278
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
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 737 of file mesh_tools.C.

References distance(), and mesh.

739 {
740  return static_cast<dof_id_type>(std::distance(mesh.active_type_elements_begin(type),
741  mesh.active_type_elements_end (type)));
742 }
MeshBase & mesh
Definition: mesh_tools.C:2278
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 772 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().

773 {
774  libmesh_parallel_only(mesh.comm());
775 
776  unsigned int nl = n_active_local_levels(mesh);
777 
778  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
779  mesh.unpartitioned_elements_end()))
780  if (elem->active())
781  nl = std::max(elem->level() + 1, nl);
782 
783  mesh.comm().max(nl);
784  return nl;
785 }
unsigned int n_active_local_levels(const MeshBase &mesh)
Definition: mesh_tools.C:760
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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 760 of file mesh_tools.C.

References mesh.

Referenced by n_active_levels().

761 {
762  unsigned int nl = 0;
763 
764  for (auto & elem : mesh.active_local_element_ptr_range())
765  nl = std::max(elem->level() + 1, nl);
766 
767  return nl;
768 }
MeshBase & mesh
Definition: mesh_tools.C:2278

◆ 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 840 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().

842 {
843  LOG_SCOPE("n_connected_components()", "MeshTools");
844 
845  // Yes, I'm being lazy. This is for mesh analysis before a
846  // simulation, not anything going in any loops.
847  if (!mesh.is_serial_on_zero())
848  libmesh_not_implemented();
849 
850  dof_id_type n_components = 0;
851 
852  if (mesh.processor_id())
853  {
854  mesh.comm().broadcast(n_components);
855  return n_components;
856  }
857 
858  // All nodes in a set here are connected (at least indirectly) to
859  // all other nodes in the same set, but have not yet been discovered
860  // to be connected to nodes in other sets.
861  std::vector<std::unordered_set<const Node *>> components;
862 
863  // With a typical mesh with few components and somewhat-contiguous
864  // ordering, vector performance should be fine. With a mesh with
865  // many components or completely scrambled ordering, performance
866  // can be a disaster.
867  auto find_component = [&components](const Node * n) {
868  std::unordered_set<const Node *> * component = nullptr;
869 
870  for (auto & c: components)
871  if (c.find(n) != c.end())
872  {
873  libmesh_assert(component == nullptr);
874  component = &c;
875  }
876 
877  return component;
878  };
879 
880  auto add_to_component =
881  [&find_component]
882  (std::unordered_set<const Node *> & component, const Node * n) {
883 
884  auto current_component = find_component(n);
885  // We may already know we're in the desired component
886  if (&component == current_component)
887  return;
888 
889  // If we're unknown, we should be in the desired component
890  else if (!current_component)
891  component.insert(n);
892 
893  // If we think we're in another component, it should actually be
894  // part of the desired component
895  else
896  {
897  component.merge(*current_component);
898  libmesh_assert(current_component->empty());
899  }
900  };
901 
902  auto & constraint_rows = mesh.get_constraint_rows();
903 
904  for (const auto & elem : mesh.element_ptr_range())
905  {
906  const Node * first_node = elem->node_ptr(0);
907 
908  auto component = find_component(first_node);
909 
910  // If we didn't find one, make a new one, reusing an existing
911  // slot if possible or growing our vector if necessary
912  if (!component)
913  for (auto & c: components)
914  if (c.empty())
915  component = &c;
916 
917  if (!component)
918  component = &components.emplace_back();
919 
920  for (const Node & n : elem->node_ref_range())
921  {
922  add_to_component(*component, &n);
923 
924  auto it = constraint_rows.find(&n);
925  if (it == constraint_rows.end())
926  continue;
927 
928  for (const auto & [pr, val] : it->second)
929  {
930  // Ignore too-trivial constraint coefficients if
931  // we get a non-default-0 constraint_tol
932  if (std::abs(val) < constraint_tol)
933  continue;
934 
935  const Elem * spline_elem = pr.first;
936  libmesh_assert(spline_elem == mesh.elem_ptr(spline_elem->id()));
937 
938  const Node * spline_node =
939  spline_elem->node_ptr(pr.second);
940 
941  add_to_component(*component, spline_node);
942  }
943  }
944  }
945 
946  for (auto & component : components)
947  if (!component.empty())
948  ++n_components;
949 
950  // We calculated this on proc 0; now let everyone else know too
951  mesh.comm().broadcast(n_components);
952 
953  return n_components;
954 }
constraint_rows_type & get_constraint_rows()
Constraint rows accessors.
Definition: mesh_base.h:1703
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:2278
virtual bool is_serial_on_zero() const
Definition: mesh_base.h:218
dof_id_type id() const
Definition: dof_object.h:828
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:2507
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 969 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(), NodalNeighborsTest::do_test(), 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(), 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().

971 {
972  return cast_int<dof_id_type>(std::distance(begin, end));
973 }
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 728 of file mesh_tools.C.

References distance(), and mesh.

730 {
731  return static_cast<dof_id_type>(std::distance(mesh.type_elements_begin(type),
732  mesh.type_elements_end (type)));
733 }
MeshBase & mesh
Definition: mesh_tools.C:2278
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 802 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::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().

803 {
804  libmesh_parallel_only(mesh.comm());
805 
806  unsigned int nl = n_local_levels(mesh);
807 
808  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
809  mesh.unpartitioned_elements_end()))
810  nl = std::max(elem->level() + 1, nl);
811 
812  mesh.comm().max(nl);
813 
814  // n_levels() is only valid and should only be called in cases where
815  // the mesh is validly distributed (or serialized). Let's run an
816  // expensive test in debug mode to make sure this is such a case.
817 #ifdef DEBUG
818  const unsigned int paranoid_nl = paranoid_n_levels(mesh);
819  libmesh_assert_equal_to(nl, paranoid_nl);
820 #endif
821  return nl;
822 }
unsigned int n_local_levels(const MeshBase &mesh)
Definition: mesh_tools.C:789
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
unsigned int paranoid_n_levels(const MeshBase &mesh)
Definition: mesh_tools.C:826
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 789 of file mesh_tools.C.

References libMesh::as_range(), and mesh.

Referenced by n_levels().

790 {
791  unsigned int nl = 0;
792 
793  for (const auto & elem : as_range(mesh.local_elements_begin(),
794  mesh.local_elements_end()))
795  nl = std::max(elem->level() + 1, nl);
796 
797  return nl;
798 }
MeshBase & mesh
Definition: mesh_tools.C:2278
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 977 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().

979 {
980  return cast_int<dof_id_type>(std::distance(begin, end));
981 }
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 744 of file mesh_tools.C.

References libMesh::as_range(), and mesh.

747 {
748  dof_id_type cnt = 0;
749 
750  // iterate over the elements of the specified type
751  for (const auto & elem : as_range(mesh.type_elements_begin(type),
752  mesh.type_elements_end(type)))
753  if ((elem->level() == level) && !elem->subactive())
754  cnt++;
755 
756  return cnt;
757 }
MeshBase & mesh
Definition: mesh_tools.C:2278
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 1014 of file mesh_tools.C.

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

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

1015 {
1016  libmesh_parallel_only(mesh.comm());
1017 
1018  unsigned int max_p_level = 0;
1019 
1020  // first my local elements
1021  for (const auto & elem : as_range(mesh.local_elements_begin(),
1022  mesh.local_elements_end()))
1023  max_p_level = std::max(elem->p_level(), max_p_level);
1024 
1025  // then any unpartitioned objects
1026  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
1027  mesh.unpartitioned_elements_end()))
1028  max_p_level = std::max(elem->p_level(), max_p_level);
1029 
1030  mesh.comm().max(max_p_level);
1031  return max_p_level + 1;
1032 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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 826 of file mesh_tools.C.

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

Referenced by n_levels().

827 {
828  libmesh_parallel_only(mesh.comm());
829 
830  unsigned int nl = 0;
831  for (const auto & elem : mesh.element_ptr_range())
832  nl = std::max(elem->level() + 1, nl);
833 
834  mesh.comm().max(nl);
835  return nl;
836 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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 663 of file mesh_tools.C.

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

665 {
666  libMesh::BoundingBox bbox =
668 
669  const Real diag = (bbox.second - bbox.first).norm();
670  const Point cent = (bbox.second + bbox.first)/2;
671 
672  return Sphere (cent, .5*diag);
673 }
This class defines a sphere.
Definition: sphere.h:72
MeshBase & mesh
Definition: mesh_tools.C:2278
auto norm(const T &a) -> decltype(std::abs(a))
Definition: tensor_tools.h:74
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
libMesh::BoundingBox create_processor_bounding_box(const MeshBase &mesh, const processor_id_type pid)
Definition: mesh_tools.C:638
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 702 of file mesh_tools.C.

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

704 {
705  libMesh::BoundingBox bbox =
707 
708  const Real diag = (bbox.second - bbox.first).norm();
709  const Point cent = (bbox.second + bbox.first)/2;
710 
711  return Sphere (cent, .5*diag);
712 }
This class defines a sphere.
Definition: sphere.h:72
MeshBase & mesh
Definition: mesh_tools.C:2278
auto norm(const T &a) -> decltype(std::abs(a))
Definition: tensor_tools.h:74
libMesh::BoundingBox create_subdomain_bounding_box(const MeshBase &mesh, const subdomain_id_type sid)
Definition: mesh_tools.C:678
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
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 414 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().

415 {
416  if (!mesh.is_serial())
417  {
418  libmesh_parallel_only(mesh.comm());
420  mesh.comm().sum(weight);
421  dof_id_type unpartitioned_weight =
422  MeshTools::weight (mesh, DofObject::invalid_processor_id);
423  return weight + unpartitioned_weight;
424  }
425 
426  SumElemWeight sew;
427 
428  Threads::parallel_reduce (ConstElemRange (mesh.elements_begin(),
429  mesh.elements_end()),
430  sew);
431  return sew.weight();
432 
433 }
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:2278
virtual bool is_serial() const
Definition: mesh_base.h:211
dof_id_type weight(const MeshBase &mesh, const processor_id_type pid)
Definition: mesh_tools.C:437
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101
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 1182 of file mesh_tools.C.

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

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

1183 {
1184  LOG_SCOPE("libmesh_assert_valid_is_prepared()", "MeshTools");
1185 
1186  if (!mesh.is_prepared())
1187  return true;
1188 
1189  std::unique_ptr<MeshBase> mesh_clone = mesh.clone();
1190 
1191  // Try preparing (without allowing repartitioning or renumbering, to
1192  // avoid false assertion failures)
1193  bool old_allow_renumbering = mesh_clone->allow_renumbering();
1194  mesh_clone->allow_renumbering(false);
1195  bool old_allow_remote_element_removal =
1196  mesh_clone->allow_remote_element_removal();
1197  bool old_skip_partitioning = mesh_clone->skip_partitioning();
1198  mesh_clone->skip_partitioning(true);
1199  mesh_clone->allow_remote_element_removal(false);
1200  mesh_clone->prepare_for_use();
1201  mesh_clone->allow_renumbering(old_allow_renumbering);
1202  mesh_clone->allow_remote_element_removal(old_allow_remote_element_removal);
1203  mesh_clone->skip_partitioning(old_skip_partitioning);
1204 
1205  return (mesh == *mesh_clone);
1206 }
bool is_prepared() const
Definition: mesh_base.h:198
MeshBase & mesh
Definition: mesh_tools.C:2278
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 985 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(), MeshTetTest::testHole(), MeshTetTest::testTetInterfaceBase(), and MeshTetTest::testTetsToTets().

987 {
988  libmesh_parallel_only(mesh.comm());
989 
990  if (dim == libMesh::invalid_uint)
991  dim = mesh.mesh_dimension();
992 
993  Real vol = 0;
994 
995  // first my local elements
996  for (const auto & elem : as_range(mesh.local_elements_begin(),
997  mesh.local_elements_end()))
998  if (elem->dim() == dim)
999  vol += elem->volume();
1000 
1001  // then count any unpartitioned objects, once
1002  if (mesh.processor_id() == 0)
1003  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
1004  mesh.unpartitioned_elements_end()))
1005  if (elem->dim() == dim)
1006  vol += elem->volume();
1007 
1008  mesh.comm().sum(vol);
1009  return vol;
1010 }
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:310
unsigned int dim
void sum(T &r) const
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2278
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:372
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 437 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(), total_weight(), and weight().

438 {
439  SumElemWeight sew;
440 
441  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
442  mesh.pid_elements_end(pid)),
443  sew);
444  return sew.weight();
445 }
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2278
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101

◆ 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