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

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

619 {
621 
622  const Real diag = (bbox.second - bbox.first).norm();
623  const Point cent = (bbox.second + bbox.first)/2;
624 
625  return Sphere (cent, .5*diag);
626 }
This class defines a sphere.
Definition: sphere.h:72
libMesh::BoundingBox create_bounding_box(const MeshBase &mesh)
Definition: mesh_tools.C:566
MeshBase & mesh
Definition: mesh_tools.C:2285
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 456 of file mesh_tools.C.

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

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

458 {
459  // A vector indexed over all nodes is too inefficient to use for a
460  // distributed mesh. Use the unordered_map API instead.
461  if (!mesh.is_serial())
462  libmesh_deprecated();
463 
464  nodes_to_elem_map.resize (mesh.max_node_id());
465 
466  for (const auto & elem : mesh.element_ptr_range())
467  for (auto & node : elem->node_ref_range())
468  {
469  libmesh_assert_less (node.id(), nodes_to_elem_map.size());
470  libmesh_assert_less (elem->id(), mesh.n_elem());
471 
472  nodes_to_elem_map[node.id()].push_back(elem->id());
473  }
474 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 478 of file mesh_tools.C.

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

480 {
481  // A vector indexed over all nodes is too inefficient to use for a
482  // distributed mesh. Use the unordered_map API instead.
483  if (!mesh.is_serial())
484  libmesh_deprecated();
485 
486  nodes_to_elem_map.resize (mesh.max_node_id());
487 
488  for (const auto & elem : mesh.element_ptr_range())
489  for (auto & node : elem->node_ref_range())
490  {
491  libmesh_assert_less (node.id(), nodes_to_elem_map.size());
492 
493  nodes_to_elem_map[node.id()].push_back(elem);
494  }
495 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 499 of file mesh_tools.C.

References mesh.

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

◆ build_nodes_to_elem_map() [4/4]

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

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

Definition at line 511 of file mesh_tools.C.

References mesh.

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

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

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

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

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

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

567 {
568  // This function must be run on all processors at once
569  libmesh_parallel_only(mesh.comm());
570 
571  FindBBox find_bbox;
572 
573  // Start with any unpartitioned elements we know about locally
574  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(DofObject::invalid_processor_id),
575  mesh.pid_elements_end(DofObject::invalid_processor_id)),
576  find_bbox);
577 
578  // And combine with our local elements
579  find_bbox.bbox().union_with(create_local_bounding_box(mesh));
580 
581  // Compare the bounding boxes across processors
582  mesh.comm().min(find_bbox.min());
583  mesh.comm().max(find_bbox.max());
584 
585  return find_bbox.bbox();
586 }
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2285
libMesh::BoundingBox create_local_bounding_box(const MeshBase &mesh)
Definition: mesh_tools.C:631
void min(const T &r, T &o, Request &req) const
void 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 631 of file mesh_tools.C.

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

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

632 {
633  FindBBox find_bbox;
634 
635  Threads::parallel_reduce (ConstElemRange (mesh.local_elements_begin(),
636  mesh.local_elements_end()),
637  find_bbox);
638 
639  return find_bbox.bbox();
640 }
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2285
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 591 of file mesh_tools.C.

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

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

592 {
593  // This function must be run on all processors at once
594  libmesh_parallel_only(mesh.comm());
595 
596  FindBBox find_bbox;
597 
598  // Start with any unpartitioned nodes we know about locally
599  Threads::parallel_reduce (ConstNodeRange (mesh.pid_nodes_begin(DofObject::invalid_processor_id),
600  mesh.pid_nodes_end(DofObject::invalid_processor_id)),
601  find_bbox);
602 
603  // Add our local nodes
604  Threads::parallel_reduce (ConstNodeRange (mesh.local_nodes_begin(),
605  mesh.local_nodes_end()),
606  find_bbox);
607 
608  // Compare the bounding boxes across processors
609  mesh.comm().min(find_bbox.min());
610  mesh.comm().max(find_bbox.max());
611 
612  return find_bbox.bbox();
613 }
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2285
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 645 of file mesh_tools.C.

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

Referenced by processor_bounding_sphere().

647 {
648  // This can only be run in parallel, with consistent arguments.
649  libmesh_parallel_only(mesh.comm());
650  libmesh_assert(mesh.comm().verify(pid));
651 
652  libmesh_assert_less (pid, mesh.n_processors());
653 
654  FindBBox find_bbox;
655 
656  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
657  mesh.pid_elements_end(pid)),
658  find_bbox);
659 
660  // Compare the bounding boxes across processors
661  mesh.comm().min(find_bbox.min());
662  mesh.comm().max(find_bbox.max());
663 
664  return find_bbox.bbox();
665 }
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2285
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 685 of file mesh_tools.C.

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

Referenced by subdomain_bounding_sphere().

687 {
688  // This can only be run in parallel, with consistent arguments.
689  libmesh_parallel_only(mesh.comm());
690  libmesh_assert(mesh.comm().verify(sid));
691 
692  FindBBox find_bbox;
693 
695  (ConstElemRange (mesh.active_local_subdomain_elements_begin(sid),
696  mesh.active_local_subdomain_elements_end(sid)),
697  find_bbox);
698 
699  // Compare the bounding boxes across processors
700  mesh.comm().min(find_bbox.min());
701  mesh.comm().max(find_bbox.max());
702 
703  return find_bbox.bbox();
704 }
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2285
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 723 of file mesh_tools.C.

References mesh.

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

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

◆ find_block_boundary_nodes()

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

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

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

Definition at line 544 of file mesh_tools.C.

References mesh.

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

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

◆ find_boundary_nodes()

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

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

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

Definition at line 524 of file mesh_tools.C.

References mesh.

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

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

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

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

References libMesh::DofObject::id().

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

1047 {
1048  find_nodal_neighbors_helper(node.id(), nodes_to_elem_map[node.id()],
1049  neighbors);
1050 }

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

References libMesh::DofObject::id().

1058 {
1059  const std::vector<const Elem *> node_to_elem_vec =
1060  libmesh_map_find(nodes_to_elem_map, node.id());
1061  find_nodal_neighbors_helper(node.id(), node_to_elem_vec, neighbors);
1062 }

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

References mesh.

967 {
968  for (const auto & elem : mesh.element_ptr_range())
969  if (!elem->subactive())
970  for (auto & n : elem->node_ref_range())
971  not_subactive_node_ids.insert(n.id());
972 }
MeshBase & mesh
Definition: mesh_tools.C:2285

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

References mesh.

1542 {
1543  for (const auto & elem : mesh.active_element_ptr_range())
1544  for (auto & node : elem->node_ref_range())
1545  libmesh_assert_equal_to
1546  (node.processor_id(),
1547  node.choose_processor_id(node.processor_id(),
1548  elem->processor_id()));
1549 }
MeshBase & mesh
Definition: mesh_tools.C:2285

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

References libMesh::libmesh_assert(), and mesh.

1650 {
1651  LOG_SCOPE("libmesh_assert_connected_nodes()", "MeshTools");
1652 
1653  std::set<const Node *> used_nodes;
1654 
1655  for (const auto & elem : mesh.element_ptr_range())
1656  {
1657  libmesh_assert (elem);
1658 
1659  for (auto & n : elem->node_ref_range())
1660  used_nodes.insert(&n);
1661  }
1662 
1663  for (const auto & node : mesh.node_ptr_range())
1664  {
1665  libmesh_assert(node);
1666  libmesh_assert(used_nodes.count(node));
1667  }
1668 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 1961 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().

1962 {
1963  libmesh_parallel_only(mesh.comm());
1964 
1965  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
1966  mesh.comm().max(parallel_max_elem_id);
1967 
1968  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
1969  {
1970  const Elem * elem = mesh.query_elem_ptr(i);
1971  processor_id_type pid =
1972  elem ? elem->processor_id() : DofObject::invalid_processor_id;
1973  mesh.comm().min(pid);
1974  libmesh_assert(elem || pid != mesh.processor_id());
1975  }
1976 
1977  dof_id_type parallel_max_node_id = mesh.max_node_id();
1978  mesh.comm().max(parallel_max_node_id);
1979 
1980  for (dof_id_type i=0; i != parallel_max_node_id; ++i)
1981  {
1982  const Node * node = mesh.query_node_ptr(i);
1983  processor_id_type pid =
1984  node ? node->processor_id() : DofObject::invalid_processor_id;
1985  mesh.comm().min(pid);
1986  libmesh_assert(node || pid != mesh.processor_id());
1987  }
1988 }
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:2285
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 1991 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().

1992 {
1993  libmesh_parallel_only(mesh.comm());
1994  auto locator = mesh.sub_point_locator();
1995 
1996  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
1997  mesh.comm().max(parallel_max_elem_id);
1998 
1999  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2000  {
2001  const Elem * elem = mesh.query_elem_ptr(i);
2002 
2003  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
2004  unsigned int n_nodes = my_n_nodes;
2005  mesh.comm().max(n_nodes);
2006 
2007  if (n_nodes)
2008  libmesh_assert(mesh.comm().semiverify(elem ? &my_n_nodes : nullptr));
2009 
2010  for (unsigned int n=0; n != n_nodes; ++n)
2011  {
2012  const Node * node = elem ? elem->node_ptr(n) : nullptr;
2013  processor_id_type pid =
2014  node ? node->processor_id() : DofObject::invalid_processor_id;
2015  mesh.comm().min(pid);
2016  libmesh_assert(node || pid != mesh.processor_id());
2017  }
2018  }
2019 }
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:1675
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:2285
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:2508
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 1404 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().

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

1629 {
1630  LOG_SCOPE("libmesh_assert_equal_connectivity()", "MeshTools");
1631 
1632  dof_id_type pmax_elem_id = mesh.max_elem_id();
1633  mesh.comm().max(pmax_elem_id);
1634 
1635  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1636  {
1637  const Elem * e = mesh.query_elem_ptr(i);
1638 
1639  std::vector<dof_id_type> nodes;
1640  if (e)
1641  for (auto n : e->node_index_range())
1642  nodes.push_back(e->node_id(n));
1643 
1644  libmesh_assert(mesh.comm().semiverify(e ? &nodes : nullptr));
1645  }
1646 }
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:2285
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:2684
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2476
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 1219 of file mesh_tools.C.

References libMesh::invalid_uint, and mesh.

1220 {
1221  LOG_SCOPE("libmesh_assert_equal_n_systems()", "MeshTools");
1222 
1223  unsigned int n_sys = libMesh::invalid_uint;
1224 
1225  for (const auto & elem : mesh.element_ptr_range())
1226  {
1227  if (n_sys == libMesh::invalid_uint)
1228  n_sys = elem->n_systems();
1229  else
1230  libmesh_assert_equal_to (elem->n_systems(), n_sys);
1231  }
1232 
1233  for (const auto & node : mesh.node_ptr_range())
1234  {
1235  if (n_sys == libMesh::invalid_uint)
1236  n_sys = node->n_systems();
1237  else
1238  libmesh_assert_equal_to (node->n_systems(), n_sys);
1239  }
1240 }
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:2285

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

1613 {
1614  LOG_SCOPE("libmesh_assert_equal_points()", "MeshTools");
1615 
1616  dof_id_type pmax_node_id = mesh.max_node_id();
1617  mesh.comm().max(pmax_node_id);
1618 
1619  for (dof_id_type i=0; i != pmax_node_id; ++i)
1620  {
1621  const Point * p = mesh.query_node_ptr(i);
1622 
1624  }
1625 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2285
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 1593 of file mesh_tools.C.

References libMesh::libmesh_assert(), and mesh.

1595 {
1596  for (const auto & elem : mesh.element_ptr_range())
1597  {
1598  libmesh_assert (elem);
1599  libmesh_assert_not_equal_to (elem->parent(), bad_elem);
1600  for (auto n : elem->neighbor_ptr_range())
1601  libmesh_assert_not_equal_to (n, bad_elem);
1602 
1603 #ifdef LIBMESH_ENABLE_AMR
1604  if (elem->has_children())
1605  for (auto & child : elem->child_ref_range())
1606  libmesh_assert_not_equal_to (&child, bad_elem);
1607 #endif
1608  }
1609 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 1245 of file mesh_tools.C.

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

1246 {
1247  LOG_SCOPE("libmesh_assert_old_dof_objects()", "MeshTools");
1248 
1249  for (const auto & elem : mesh.element_ptr_range())
1250  {
1251  if (elem->refinement_flag() == Elem::JUST_REFINED ||
1252  elem->refinement_flag() == Elem::INACTIVE)
1253  continue;
1254 
1255  if (elem->has_dofs())
1256  libmesh_assert(elem->get_old_dof_object());
1257 
1258  for (auto & node : elem->node_ref_range())
1259  if (node.has_dofs())
1260  libmesh_assert(node.get_old_dof_object());
1261  }
1262 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 2072 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().

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

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

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

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

◆ libmesh_assert_topology_consistent_procids< Node >()

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

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

1349 {
1350  LOG_SCOPE("libmesh_assert_valid_amr_elem_ids()", "MeshTools");
1351 
1352  for (const auto & elem : mesh.element_ptr_range())
1353  {
1354  libmesh_assert (elem);
1355 
1356  const Elem * parent = elem->parent();
1357 
1358  if (parent)
1359  {
1360  libmesh_assert_greater_equal (elem->id(), parent->id());
1361  libmesh_assert_greater_equal (elem->processor_id(), parent->processor_id());
1362  }
1363  }
1364 }
const Elem * parent() const
Definition: elem.h:3031
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2285
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 1368 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().

1369 {
1370  LOG_SCOPE("libmesh_assert_valid_amr_interior_parents()", "MeshTools");
1371 
1372  for (const auto & elem : mesh.element_ptr_range())
1373  {
1374  libmesh_assert (elem);
1375 
1376  // We can skip to the next element if we're full-dimension
1377  // and therefore don't have any interior parents
1378  if (elem->dim() >= LIBMESH_DIM)
1379  continue;
1380 
1381  const Elem * ip = elem->interior_parent();
1382 
1383  const Elem * parent = elem->parent();
1384 
1385  if (ip && (ip != remote_elem) && parent)
1386  {
1387  libmesh_assert_equal_to (ip->top_parent(),
1388  elem->top_parent()->interior_parent());
1389 
1390  if (ip->level() == elem->level())
1391  libmesh_assert_equal_to (ip->parent(),
1392  parent->interior_parent());
1393  else
1394  {
1395  libmesh_assert_less (ip->level(), elem->level());
1396  libmesh_assert_equal_to (ip, parent->interior_parent());
1397  }
1398  }
1399  }
1400 }
const Elem * parent() const
Definition: elem.h:3031
const Elem * interior_parent() const
Definition: elem.C:1184
const Elem * top_parent() const
Definition: elem.h:3057
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
Definition: mesh_tools.C:2285
libmesh_assert(ctx)
unsigned int level() const
Definition: elem.h:3075
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 1715 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().

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

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

1886 {
1887  LOG_SCOPE("libmesh_assert_valid_dof_ids()", "MeshTools");
1888 
1889  if (mesh.n_processors() == 1)
1890  return;
1891 
1892  libmesh_parallel_only(mesh.comm());
1893 
1894  dof_id_type pmax_elem_id = mesh.max_elem_id();
1895  mesh.comm().max(pmax_elem_id);
1896 
1897  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1898  assert_semiverify_dofobj(mesh.comm(),
1899  mesh.query_elem_ptr(i),
1900  sysnum);
1901 
1902  dof_id_type pmax_node_id = mesh.max_node_id();
1903  mesh.comm().max(pmax_node_id);
1904 
1905  for (dof_id_type i=0; i != pmax_node_id; ++i)
1906  assert_semiverify_dofobj(mesh.comm(),
1907  mesh.query_node_ptr(i),
1908  sysnum);
1909 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2285
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 1325 of file mesh_tools.C.

References libMesh::libmesh_assert(), and mesh.

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

1326 {
1327  LOG_SCOPE("libmesh_assert_valid_elem_ids()", "MeshTools");
1328 
1329  processor_id_type lastprocid = 0;
1330  dof_id_type lastelemid = 0;
1331 
1332  for (const auto & elem : mesh.active_element_ptr_range())
1333  {
1334  libmesh_assert (elem);
1335  processor_id_type elemprocid = elem->processor_id();
1336  dof_id_type elemid = elem->id();
1337 
1338  libmesh_assert_greater_equal (elemid, lastelemid);
1339  libmesh_assert_greater_equal (elemprocid, lastprocid);
1340 
1341  lastelemid = elemid;
1342  lastprocid = elemprocid;
1343  }
1344 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 2212 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().

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

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

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

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

1555 {
1556  LOG_SCOPE("libmesh_assert_valid_refinement_tree()", "MeshTools");
1557 
1558  for (const auto & elem : mesh.element_ptr_range())
1559  {
1560  libmesh_assert(elem);
1561  if (elem->has_children())
1562  for (auto & child : elem->child_ref_range())
1563  if (&child != remote_elem)
1564  libmesh_assert_equal_to (child.parent(), elem);
1565  if (elem->active())
1566  {
1567  libmesh_assert(!elem->ancestor());
1568  libmesh_assert(!elem->subactive());
1569  }
1570  else if (elem->ancestor())
1571  {
1572  libmesh_assert(!elem->subactive());
1573  }
1574  else
1575  libmesh_assert(elem->subactive());
1576 
1577  if (elem->p_refinement_flag() == Elem::JUST_REFINED)
1578  libmesh_assert_greater(elem->p_level(), 0);
1579  }
1580 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 1294 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().

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

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

References distance(), and mesh.

746 {
747  return static_cast<dof_id_type>(std::distance(mesh.active_type_elements_begin(type),
748  mesh.active_type_elements_end (type)));
749 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 779 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().

780 {
781  libmesh_parallel_only(mesh.comm());
782 
783  unsigned int nl = n_active_local_levels(mesh);
784 
785  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
786  mesh.unpartitioned_elements_end()))
787  if (elem->active())
788  nl = std::max(elem->level() + 1, nl);
789 
790  mesh.comm().max(nl);
791  return nl;
792 }
unsigned int n_active_local_levels(const MeshBase &mesh)
Definition: mesh_tools.C:767
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2285
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
void max(const T &r, T &o, Request &req) const

◆ n_active_local_levels()

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

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

Definition at line 767 of file mesh_tools.C.

References mesh.

Referenced by n_active_levels().

768 {
769  unsigned int nl = 0;
770 
771  for (auto & elem : mesh.active_local_element_ptr_range())
772  nl = std::max(elem->level() + 1, nl);
773 
774  return nl;
775 }
MeshBase & mesh
Definition: mesh_tools.C:2285

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

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

References distance().

Referenced by libMesh::MeshTools::Subdivision::add_boundary_ghosts(), add_cube_convex_hull_to_mesh(), correct_node_proc_ids(), libMesh::RBEIMEvaluation::get_interior_basis_function_sizes(), main(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::XdrIO::read(), libMesh::STLIO::read_binary(), libMesh::XdrIO::read_header(), libMesh::RBEIMEvaluation::read_in_interior_basis_functions(), libMesh::DynaIO::read_mesh(), libMesh::XdrIO::read_serialized_connectivity(), libMesh::System::read_serialized_vector(), libMesh::System::read_serialized_vectors(), libMesh::Partitioner::set_node_processor_ids(), libMesh::Partitioner::set_parent_processor_ids(), 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().

978 {
979  return cast_int<dof_id_type>(std::distance(begin, end));
980 }
Real distance(const Point &p)

◆ n_elem_of_type()

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

Implemented in terms of type_element_iterators.

Definition at line 735 of file mesh_tools.C.

References distance(), and mesh.

737 {
738  return static_cast<dof_id_type>(std::distance(mesh.type_elements_begin(type),
739  mesh.type_elements_end (type)));
740 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 809 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().

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

References libMesh::as_range(), and mesh.

Referenced by n_levels().

797 {
798  unsigned int nl = 0;
799 
800  for (const auto & elem : as_range(mesh.local_elements_begin(),
801  mesh.local_elements_end()))
802  nl = std::max(elem->level() + 1, nl);
803 
804  return nl;
805 }
MeshBase & mesh
Definition: mesh_tools.C:2285
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 984 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().

986 {
987  return cast_int<dof_id_type>(std::distance(begin, end));
988 }
Real distance(const Point &p)

◆ n_non_subactive_elem_of_type_at_level()

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

Definition at line 751 of file mesh_tools.C.

References libMesh::as_range(), and mesh.

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

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

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

1022 {
1023  libmesh_parallel_only(mesh.comm());
1024 
1025  unsigned int max_p_level = 0;
1026 
1027  // first my local elements
1028  for (const auto & elem : as_range(mesh.local_elements_begin(),
1029  mesh.local_elements_end()))
1030  max_p_level = std::max(elem->p_level(), max_p_level);
1031 
1032  // then any unpartitioned objects
1033  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
1034  mesh.unpartitioned_elements_end()))
1035  max_p_level = std::max(elem->p_level(), max_p_level);
1036 
1037  mesh.comm().max(max_p_level);
1038  return max_p_level + 1;
1039 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2285
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 833 of file mesh_tools.C.

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

Referenced by n_levels().

834 {
835  libmesh_parallel_only(mesh.comm());
836 
837  unsigned int nl = 0;
838  for (const auto & elem : mesh.element_ptr_range())
839  nl = std::max(elem->level() + 1, nl);
840 
841  mesh.comm().max(nl);
842  return nl;
843 }
const Parallel::Communicator & comm() const
MeshBase & mesh
Definition: mesh_tools.C:2285
void max(const T &r, T &o, Request &req) const

◆ processor_bounding_sphere()

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

Definition at line 670 of file mesh_tools.C.

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

672 {
673  libMesh::BoundingBox bbox =
675 
676  const Real diag = (bbox.second - bbox.first).norm();
677  const Point cent = (bbox.second + bbox.first)/2;
678 
679  return Sphere (cent, .5*diag);
680 }
This class defines a sphere.
Definition: sphere.h:72
MeshBase & mesh
Definition: mesh_tools.C:2285
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:645
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39

◆ subdomain_bounding_sphere()

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

Definition at line 709 of file mesh_tools.C.

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

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

◆ total_weight()

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

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

Definition at line 421 of file mesh_tools.C.

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

422 {
423  if (!mesh.is_serial())
424  {
425  libmesh_parallel_only(mesh.comm());
427  mesh.comm().sum(weight);
428  dof_id_type unpartitioned_weight =
429  MeshTools::weight (mesh, DofObject::invalid_processor_id);
430  return weight + unpartitioned_weight;
431  }
432 
433  SumElemWeight sew;
434 
435  Threads::parallel_reduce (ConstElemRange (mesh.elements_begin(),
436  mesh.elements_end()),
437  sew);
438  return sew.weight();
439 
440 }
void sum(T &r) const
const Parallel::Communicator & comm() const
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2285
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:444
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 1189 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().

1190 {
1191  LOG_SCOPE("libmesh_assert_valid_is_prepared()", "MeshTools");
1192 
1193  if (!mesh.is_prepared())
1194  return true;
1195 
1196  std::unique_ptr<MeshBase> mesh_clone = mesh.clone();
1197 
1198  // Try preparing (without allowing repartitioning or renumbering, to
1199  // avoid false assertion failures)
1200  bool old_allow_renumbering = mesh_clone->allow_renumbering();
1201  mesh_clone->allow_renumbering(false);
1202  bool old_allow_remote_element_removal =
1203  mesh_clone->allow_remote_element_removal();
1204  bool old_skip_partitioning = mesh_clone->skip_partitioning();
1205  mesh_clone->skip_partitioning(true);
1206  mesh_clone->allow_remote_element_removal(false);
1207  mesh_clone->prepare_for_use();
1208  mesh_clone->allow_renumbering(old_allow_renumbering);
1209  mesh_clone->allow_remote_element_removal(old_allow_remote_element_removal);
1210  mesh_clone->skip_partitioning(old_skip_partitioning);
1211 
1212  return (mesh == *mesh_clone);
1213 }
bool is_prepared() const
Definition: mesh_base.h:198
MeshBase & mesh
Definition: mesh_tools.C:2285
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 992 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().

994 {
995  libmesh_parallel_only(mesh.comm());
996 
997  if (dim == libMesh::invalid_uint)
998  dim = mesh.mesh_dimension();
999 
1000  Real vol = 0;
1001 
1002  // first my local elements
1003  for (const auto & elem : as_range(mesh.local_elements_begin(),
1004  mesh.local_elements_end()))
1005  if (elem->dim() == dim)
1006  vol += elem->volume();
1007 
1008  // then count any unpartitioned objects, once
1009  if (mesh.processor_id() == 0)
1010  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
1011  mesh.unpartitioned_elements_end()))
1012  if (elem->dim() == dim)
1013  vol += elem->volume();
1014 
1015  mesh.comm().sum(vol);
1016  return vol;
1017 }
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:2285
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 444 of file mesh_tools.C.

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

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

445 {
446  SumElemWeight sew;
447 
448  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
449  mesh.pid_elements_end(pid)),
450  sew);
451  return sew.weight();
452 }
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:54
MeshBase & mesh
Definition: mesh_tools.C:2285
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