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  BoundingBox
 Backwards compatibility with forward declarations. 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...
 
void find_boundary_nodes (const MeshBase &mesh, std::vector< bool > &on_boundary)
 
std::unordered_set< dof_id_typefind_boundary_nodes (const MeshBase &mesh)
 Returns a std::set containing Node IDs for all of the boundary nodes. 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...
 
BoundingBox bounding_box (const MeshBase &mesh)
 
libMesh::BoundingBox create_bounding_box (const MeshBase &mesh)
 The same functionality as the deprecated MeshTools::bounding_box(). More...
 
Sphere bounding_sphere (const MeshBase &mesh)
 
libMesh::BoundingBox create_nodal_bounding_box (const MeshBase &mesh)
 
libMesh::BoundingBox create_local_bounding_box (const MeshBase &mesh)
 
BoundingBox processor_bounding_box (const MeshBase &mesh, const processor_id_type pid)
 
libMesh::BoundingBox create_processor_bounding_box (const MeshBase &mesh, const processor_id_type pid)
 The same functionality as the deprecated MeshTools::processor_bounding_box(). More...
 
Sphere processor_bounding_sphere (const MeshBase &mesh, const processor_id_type pid)
 
BoundingBox subdomain_bounding_box (const MeshBase &mesh, const subdomain_id_type sid)
 
libMesh::BoundingBox create_subdomain_bounding_box (const MeshBase &mesh, const subdomain_id_type sid)
 The same functionality as the deprecated MeshTools::subdomain_bounding_box(). More...
 
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)
 
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...
 
unsigned int max_level (const MeshBase &mesh)
 Find the maximum h-refinement level in a mesh. 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 libmesh_assert_no_links_to_elem (const MeshBase &mesh, const Elem *bad_elem)
 A function for verifying that an element has been cut off from the rest of the mesh. More...
 
void libmesh_assert_equal_n_systems (const MeshBase &mesh)
 A function for testing that all DofObjects within a mesh have the same n_systems count. 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_connected_nodes (const MeshBase &mesh)
 A function for verifying that all nodes are connected to at least one element. 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_contiguous_dof_ids (const MeshBase &mesh, unsigned int sysnum)
 A function for verifying that degree of freedom indexes are contiguous on each processors, as is required by libMesh numeric classes. 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 recieved 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_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...
 
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_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_flags (const MeshBase &mesh)
 A function for verifying that refinement flags on elements are consistent between processors. 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_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...
 
template<>
void libmesh_assert_topology_consistent_procids< Elem > (const MeshBase &mesh)
 
template<>
void libmesh_assert_parallel_consistent_procids< Elem > (const MeshBase &mesh)
 
template<>
void libmesh_assert_topology_consistent_procids< Node > (const MeshBase &mesh)
 
template<>
void libmesh_assert_parallel_consistent_procids< Node > (const MeshBase &mesh)
 

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_box()

MeshTools::BoundingBox libMesh::MeshTools::bounding_box ( const MeshBase mesh)
Returns
Two points defining a cartesian box that bounds the mesh. The first entry in the pair is the minimum, the second is the maximum.

Definition at line 376 of file mesh_tools.C.

377 {
378  // This function is deprecated. It simply calls
379  // create_bounding_box() and converts the result to a
380  // MeshTools::BoundingBox.
381  libmesh_deprecated();
383 }

References create_bounding_box(), and mesh.

Referenced by libMesh::TreeNode< N >::bounds_point(), libMesh::TreeNode< N >::create_bounding_box(), libMesh::TreeNode< N >::insert(), and libMesh::TreeNode< N >::set_bounding_box().

◆ bounding_sphere()

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

Definition at line 441 of file mesh_tools.C.

442 {
444 
445  const Real diag = (bbox.second - bbox.first).norm();
446  const Point cent = (bbox.second + bbox.first)/2;
447 
448  return Sphere (cent, .5*diag);
449 }

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

◆ build_nodes_to_elem_map() [1/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 293 of file mesh_tools.C.

295 {
296  nodes_to_elem_map.clear();
297 
298  for (const auto & elem : mesh.element_ptr_range())
299  for (auto & node : elem->node_ref_range())
300  nodes_to_elem_map[node.id()].push_back(elem);
301 }

References libMesh::MeshBase::element_ptr_range(), and mesh.

◆ build_nodes_to_elem_map() [2/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 281 of file mesh_tools.C.

283 {
284  nodes_to_elem_map.clear();
285 
286  for (const auto & elem : mesh.element_ptr_range())
287  for (auto & node : elem->node_ref_range())
288  nodes_to_elem_map[node.id()].push_back(elem->id());
289 }

References libMesh::MeshBase::element_ptr_range(), and mesh.

◆ build_nodes_to_elem_map() [3/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 265 of file mesh_tools.C.

267 {
268  nodes_to_elem_map.resize (mesh.n_nodes());
269 
270  for (const auto & elem : mesh.element_ptr_range())
271  for (auto & node : elem->node_ref_range())
272  {
273  libmesh_assert_less (node.id(), nodes_to_elem_map.size());
274 
275  nodes_to_elem_map[node.id()].push_back(elem);
276  }
277 }

References libMesh::MeshBase::element_ptr_range(), mesh, and libMesh::MeshBase::n_nodes().

◆ build_nodes_to_elem_map() [4/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 248 of file mesh_tools.C.

250 {
251  nodes_to_elem_map.resize (mesh.n_nodes());
252 
253  for (const auto & elem : mesh.element_ptr_range())
254  for (auto & node : elem->node_ref_range())
255  {
256  libmesh_assert_less (node.id(), nodes_to_elem_map.size());
257  libmesh_assert_less (elem->id(), mesh.n_elem());
258 
259  nodes_to_elem_map[node.id()].push_back(elem->id());
260  }
261 }

References libMesh::MeshBase::element_ptr_range(), mesh, libMesh::MeshBase::n_elem(), and libMesh::MeshBase::n_nodes().

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

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

2253 {
2254  LOG_SCOPE("correct_node_proc_ids()","MeshTools");
2255 
2256  // This function must be run on all processors at once
2257  libmesh_parallel_only(mesh.comm());
2258 
2259  // We require all processors to agree on nodal processor ids before
2260  // going into this algorithm.
2261 #ifdef DEBUG
2263 #endif
2264 
2265  // If we have any unpartitioned elements at this
2266  // stage there is a problem
2269 
2270  // Fix nodes' processor ids. Coarsening may have left us with nodes
2271  // which are no longer touched by any elements of the same processor
2272  // id, and for DofMap to work we need to fix that.
2273 
2274  // This is harder now that libMesh no longer requires a distributed
2275  // mesh to ghost all nodal neighbors: it is possible for two active
2276  // elements on two different processors to share the same node in
2277  // such a way that neither processor knows the others' element
2278  // exists!
2279 
2280  // While we're at it, if this mesh is configured to allow
2281  // repartitioning, we'll repartition *all* the nodes' processor ids
2282  // using the canonical Node heuristic, to try and improve DoF load
2283  // balancing. But if the mesh is disallowing repartitioning, we
2284  // won't touch processor_id on any node where it's valid, regardless
2285  // of whether or not it's canonical.
2286  bool repartition_all_nodes = !mesh.skip_noncritical_partitioning();
2287  std::unordered_set<const Node *> valid_nodes;
2288 
2289  // If we aren't allowed to repartition, then we're going to leave
2290  // every node we can at its current processor_id, and *only*
2291  // repartition the nodes whose current processor id is incompatible
2292  // with DoFMap (because it doesn't touch an active element, e.g. due
2293  // to coarsening)
2294  if (!repartition_all_nodes)
2295  {
2296  for (const auto & elem : mesh.active_element_ptr_range())
2297  for (const auto & node : elem->node_ref_range())
2298  if (elem->processor_id() == node.processor_id())
2299  valid_nodes.insert(&node);
2300 
2301  SyncNodeSet syncv(valid_nodes, mesh);
2302 
2304  (mesh.comm(), mesh.nodes_begin(), mesh.nodes_end(), syncv);
2305  }
2306 
2307  // We build up a set of compatible processor ids for each node
2308  proc_id_map_type new_proc_ids;
2309 
2310  for (auto & elem : mesh.active_element_ptr_range())
2311  {
2312  processor_id_type pid = elem->processor_id();
2313 
2314  for (auto & node : elem->node_ref_range())
2315  {
2316  const dof_id_type id = node.id();
2317  const proc_id_map_type::iterator it = new_proc_ids.find(id);
2318  if (it == new_proc_ids.end())
2319  new_proc_ids.insert(std::make_pair(id,pid));
2320  else
2321  it->second = node.choose_processor_id(it->second, pid);
2322  }
2323  }
2324 
2325  // Sort the new pids to push to each processor
2326  std::map<processor_id_type, std::vector<std::pair<dof_id_type, processor_id_type>>>
2327  ids_to_push;
2328 
2329  for (const auto & node : mesh.node_ptr_range())
2330  {
2331  const dof_id_type id = node->id();
2332  const proc_id_map_type::iterator it = new_proc_ids.find(id);
2333  if (it == new_proc_ids.end())
2334  continue;
2335  const processor_id_type pid = it->second;
2336  if (node->processor_id() != DofObject::invalid_processor_id)
2337  ids_to_push[node->processor_id()].push_back(std::make_pair(id, pid));
2338  }
2339 
2340  auto action_functor =
2341  [& mesh, & new_proc_ids]
2343  const std::vector<std::pair<dof_id_type, processor_id_type>> & data)
2344  {
2345  for (auto & p : data)
2346  {
2347  const dof_id_type id = p.first;
2348  const processor_id_type pid = p.second;
2349  const proc_id_map_type::iterator it = new_proc_ids.find(id);
2350  if (it == new_proc_ids.end())
2351  new_proc_ids.insert(std::make_pair(id,pid));
2352  else
2353  {
2354  const Node & node = mesh.node_ref(id);
2355  it->second = node.choose_processor_id(it->second, pid);
2356  }
2357  }
2358  };
2359 
2360  Parallel::push_parallel_vector_data
2361  (mesh.comm(), ids_to_push, action_functor);
2362 
2363  // Now new_proc_ids is correct for every node we used to own. Let's
2364  // ask every other processor about the nodes they used to own. But
2365  // first we'll need to keep track of which nodes we used to own,
2366  // lest we get them confused with nodes we newly own.
2367  std::unordered_set<Node *> ex_local_nodes;
2368  for (auto & node : mesh.local_node_ptr_range())
2369  {
2370  const proc_id_map_type::iterator it = new_proc_ids.find(node->id());
2371  if (it != new_proc_ids.end() && it->second != mesh.processor_id())
2372  ex_local_nodes.insert(node);
2373  }
2374 
2375  SyncProcIdsFromMap sync(new_proc_ids, mesh);
2376  if (repartition_all_nodes)
2378  (mesh.comm(), mesh.nodes_begin(), mesh.nodes_end(), sync);
2379  else
2380  {
2381  NodesNotInSet nnis(valid_nodes);
2382 
2384  (mesh.comm(), mesh.nodes_begin(), mesh.nodes_end(), nnis, sync);
2385  }
2386 
2387  // And finally let's update the nodes we used to own.
2388  for (const auto & node : ex_local_nodes)
2389  {
2390  if (valid_nodes.count(node))
2391  continue;
2392 
2393  const dof_id_type id = node->id();
2394  const proc_id_map_type::iterator it = new_proc_ids.find(id);
2395  libmesh_assert(it != new_proc_ids.end());
2396  node->processor_id() = it->second;
2397  }
2398 
2399  // We should still have consistent nodal processor ids coming out of
2400  // this algorithm, but if we're allowed to repartition the mesh then
2401  // they should be canonically correct too.
2402 #ifdef DEBUG
2403  MeshTools::libmesh_assert_valid_procids<Node>(mesh);
2404  //if (repartition_all_nodes)
2405  // MeshTools::libmesh_assert_canonical_node_procids(mesh);
2406 #endif
2407 }

References libMesh::MeshBase::active_element_ptr_range(), libMesh::Node::choose_processor_id(), libMesh::ParallelObject::comm(), data, libMesh::libmesh_assert(), libmesh_assert_parallel_consistent_procids< Node >(), libMesh::MeshBase::local_node_ptr_range(), mesh, n_elem(), new_proc_ids, libMesh::MeshBase::node_ptr_range(), libMesh::MeshBase::node_ref(), libMesh::MeshBase::nodes_begin(), libMesh::MeshBase::nodes_end(), libMesh::ParallelObject::processor_id(), libMesh::MeshBase::skip_noncritical_partitioning(), libMesh::Parallel::sync_dofobject_data_by_id(), libMesh::MeshBase::unpartitioned_elements_begin(), and libMesh::MeshBase::unpartitioned_elements_end().

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

◆ create_bounding_box()

libMesh::BoundingBox libMesh::MeshTools::create_bounding_box ( const MeshBase mesh)

The same functionality as the deprecated MeshTools::bounding_box().

Returns
The non-deprecated libMesh::BoundingBox type.

Definition at line 389 of file mesh_tools.C.

390 {
391  // This function must be run on all processors at once
392  libmesh_parallel_only(mesh.comm());
393 
394  FindBBox find_bbox;
395 
396  // Start with any unpartitioned elements we know about locally
397  Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(DofObject::invalid_processor_id),
398  mesh.pid_elements_end(DofObject::invalid_processor_id)),
399  find_bbox);
400 
401  // And combine with our local elements
402  find_bbox.bbox().union_with(MeshTools::create_local_bounding_box(mesh));
403 
404  // Compare the bounding boxes across processors
405  mesh.comm().min(find_bbox.min());
406  mesh.comm().max(find_bbox.max());
407 
408  return find_bbox.bbox();
409 }

References libMesh::ParallelObject::comm(), create_local_bounding_box(), libMesh::DofObject::invalid_processor_id, mesh, libMesh::Threads::parallel_reduce(), libMesh::MeshBase::pid_elements_begin(), and libMesh::MeshBase::pid_elements_end().

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

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

455 {
456  FindBBox find_bbox;
457 
460  find_bbox);
461 
462  return find_bbox.bbox();
463 }

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

Referenced by create_bounding_box().

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

415 {
416  // This function must be run on all processors at once
417  libmesh_parallel_only(mesh.comm());
418 
419  FindBBox find_bbox;
420 
421  // Start with any unpartitioned nodes we know about locally
422  Threads::parallel_reduce (ConstNodeRange (mesh.pid_nodes_begin(DofObject::invalid_processor_id),
423  mesh.pid_nodes_end(DofObject::invalid_processor_id)),
424  find_bbox);
425 
426  // Add our local nodes
429  find_bbox);
430 
431  // Compare the bounding boxes across processors
432  mesh.comm().min(find_bbox.min());
433  mesh.comm().max(find_bbox.max());
434 
435  return find_bbox.bbox();
436 }

References libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, libMesh::MeshBase::local_nodes_begin(), libMesh::MeshBase::local_nodes_end(), mesh, libMesh::Threads::parallel_reduce(), libMesh::MeshBase::pid_nodes_begin(), and libMesh::MeshBase::pid_nodes_end().

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

◆ create_processor_bounding_box()

libMesh::BoundingBox libMesh::MeshTools::create_processor_bounding_box ( const MeshBase mesh,
const processor_id_type  pid 
)

The same functionality as the deprecated MeshTools::processor_bounding_box().

Returns
The non-deprecated libMesh::BoundingBox type.

Definition at line 480 of file mesh_tools.C.

482 {
483  // This can only be run in parallel, with consistent arguments.
484  libmesh_parallel_only(mesh.comm());
485  libmesh_assert(mesh.comm().verify(pid));
486 
487  libmesh_assert_less (pid, mesh.n_processors());
488 
489  FindBBox find_bbox;
490 
492  mesh.pid_elements_end(pid)),
493  find_bbox);
494 
495  // Compare the bounding boxes across processors
496  mesh.comm().min(find_bbox.min());
497  mesh.comm().max(find_bbox.max());
498 
499  return find_bbox.bbox();
500 }

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), mesh, libMesh::ParallelObject::n_processors(), libMesh::Threads::parallel_reduce(), libMesh::MeshBase::pid_elements_begin(), and libMesh::MeshBase::pid_elements_end().

Referenced by processor_bounding_box(), and processor_bounding_sphere().

◆ create_subdomain_bounding_box()

libMesh::BoundingBox libMesh::MeshTools::create_subdomain_bounding_box ( const MeshBase mesh,
const subdomain_id_type  sid 
)

The same functionality as the deprecated MeshTools::subdomain_bounding_box().

Returns
The non-deprecated libMesh::BoundingBox type.

Definition at line 532 of file mesh_tools.C.

534 {
535  // This can only be run in parallel, with consistent arguments.
536  libmesh_parallel_only(mesh.comm());
537  libmesh_assert(mesh.comm().verify(sid));
538 
539  FindBBox find_bbox;
540 
544  find_bbox);
545 
546  // Compare the bounding boxes across processors
547  mesh.comm().min(find_bbox.min());
548  mesh.comm().max(find_bbox.max());
549 
550  return find_bbox.bbox();
551 }

References libMesh::MeshBase::active_local_subdomain_elements_begin(), libMesh::MeshBase::active_local_subdomain_elements_end(), libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), mesh, and libMesh::Threads::parallel_reduce().

Referenced by subdomain_bounding_box(), and subdomain_bounding_sphere().

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

572 {
573  // Loop over the the elements. If the current element type isn't in
574  // the vector, insert it.
575  for (const auto & elem : mesh.element_ptr_range())
576  if (!std::count(et.begin(), et.end(), elem->type()))
577  et.push_back(elem->type());
578 }

References libMesh::MeshBase::element_ptr_range(), and mesh.

◆ 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 elemenents from 2 or more blockse

Definition at line 354 of file mesh_tools.C.

355 {
356  std::unordered_set<dof_id_type> block_boundary_nodes;
357 
358  // Loop over elements, find those on boundary, and
359  // mark them as true in on_boundary.
360  for (const auto & elem : mesh.active_element_ptr_range())
361  for (auto s : elem->side_index_range())
362  if (elem->neighbor_ptr(s) && (elem->neighbor_ptr(s)->subdomain_id() != elem->subdomain_id()))
363  {
364  auto nodes_on_side = elem->nodes_on_side(s);
365 
366  for (auto & local_id : nodes_on_side)
367  block_boundary_nodes.insert(elem->node_ptr(local_id)->id());
368  }
369 
370  return block_boundary_nodes;
371 }

References libMesh::MeshBase::active_element_ptr_range(), and mesh.

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

◆ find_boundary_nodes() [1/2]

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

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

Definition at line 334 of file mesh_tools.C.

335 {
336  std::unordered_set<dof_id_type> boundary_nodes;
337 
338  // Loop over elements, find those on boundary, and
339  // mark them as true in on_boundary.
340  for (const auto & elem : mesh.active_element_ptr_range())
341  for (auto s : elem->side_index_range())
342  if (elem->neighbor_ptr(s) == nullptr) // on the boundary
343  {
344  auto nodes_on_side = elem->nodes_on_side(s);
345 
346  for (auto & local_id : nodes_on_side)
347  boundary_nodes.insert(elem->node_ptr(local_id)->id());
348  }
349 
350  return boundary_nodes;
351 }

References libMesh::MeshBase::active_element_ptr_range(), and mesh.

◆ find_boundary_nodes() [2/2]

void libMesh::MeshTools::find_boundary_nodes ( const MeshBase mesh,
std::vector< bool > &  on_boundary 
)
    Calling this function on a 2D mesh will convert all the elements
    to triangles.  \p QUAD4s will be converted to \p TRI3s, \p QUAD8s
    and \p QUAD9s will be converted to \p TRI6s.
   &zwj;/

void all_tri (MeshBase & mesh);

#ifdef LIBMESH_ENABLE_DEPRECATED /** Fills the vector "on_boundary" with flags that tell whether each node is on the domain boundary (true)) or not (false).

Definition at line 306 of file mesh_tools.C.

308 {
309  libmesh_deprecated();
310 
311  // Resize the vector which holds boundary nodes and fill with false.
312  on_boundary.resize(mesh.max_node_id());
313  std::fill(on_boundary.begin(),
314  on_boundary.end(),
315  false);
316 
317  // Loop over elements, find those on boundary, and
318  // mark them as true in on_boundary.
319  for (const auto & elem : mesh.active_element_ptr_range())
320  for (auto s : elem->side_index_range())
321  if (elem->neighbor_ptr(s) == nullptr) // on the boundary
322  {
323  std::unique_ptr<const Elem> side = elem->build_side_ptr(s);
324 
325  auto nodes_on_side = elem->nodes_on_side(s);
326 
327  for (auto & node_id : nodes_on_side)
328  on_boundary[node_id] = true;
329  }
330 }

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

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

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

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

References libMesh::MeshBase::active_local_element_ptr_range(), 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().

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

◆ find_nodal_neighbors() [1/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 909 of file mesh_tools.C.

913 {
914  // We'll refer back to the Node ID several times
915  dof_id_type global_id = node.id();
916 
917  // We'll construct a std::set<const Node *> for more efficient
918  // searching while finding the nodal neighbors, and return it to the
919  // user in a std::vector.
920  std::set<const Node *> neighbor_set;
921 
922  // List of Elems attached to this node.
923  const auto & elem_vec = libmesh_map_find(nodes_to_elem_map, global_id);
924 
925  // Look through the elements that contain this node
926  // find the local node id... then find the side that
927  // node lives on in the element
928  // next, look for the _other_ node on that side
929  // That other node is a "nodal_neighbor"... save it
930  for (const auto & elem : elem_vec)
931  {
932  // We only care about active elements...
933  if (elem->active())
934  {
935  // Which local node number is global_id?
936  unsigned local_node_number = elem->local_node(global_id);
937 
938  // Make sure it was found
939  libmesh_assert_not_equal_to(local_node_number, libMesh::invalid_uint);
940 
941  const unsigned short n_edges = elem->n_edges();
942 
943  // If this element has no edges, the edge-based algorithm below doesn't make sense.
944  if (!n_edges)
945  {
946  switch (elem->type())
947  {
948  case EDGE2:
949  {
950  switch (local_node_number)
951  {
952  case 0:
953  // The other node is a nodal neighbor
954  neighbor_set.insert(elem->node_ptr(1));
955  break;
956 
957  case 1:
958  // The other node is a nodal neighbor
959  neighbor_set.insert(elem->node_ptr(0));
960  break;
961 
962  default:
963  libmesh_error_msg("Invalid local node number: " << local_node_number << " found." << std::endl);
964  }
965  break;
966  }
967 
968  case EDGE3:
969  {
970  switch (local_node_number)
971  {
972  // The outside nodes have node 2 as a neighbor
973  case 0:
974  case 1:
975  neighbor_set.insert(elem->node_ptr(2));
976  break;
977 
978  // The middle node has the outer nodes as neighbors
979  case 2:
980  neighbor_set.insert(elem->node_ptr(0));
981  neighbor_set.insert(elem->node_ptr(1));
982  break;
983 
984  default:
985  libmesh_error_msg("Invalid local node number: " << local_node_number << " found." << std::endl);
986  }
987  break;
988  }
989 
990  case EDGE4:
991  {
992  switch (local_node_number)
993  {
994  case 0:
995  // The left-middle node is a nodal neighbor
996  neighbor_set.insert(elem->node_ptr(2));
997  break;
998 
999  case 1:
1000  // The right-middle node is a nodal neighbor
1001  neighbor_set.insert(elem->node_ptr(3));
1002  break;
1003 
1004  // The left-middle node
1005  case 2:
1006  neighbor_set.insert(elem->node_ptr(0));
1007  neighbor_set.insert(elem->node_ptr(3));
1008  break;
1009 
1010  // The right-middle node
1011  case 3:
1012  neighbor_set.insert(elem->node_ptr(1));
1013  neighbor_set.insert(elem->node_ptr(2));
1014  break;
1015 
1016  default:
1017  libmesh_error_msg("Invalid local node number: " << local_node_number << " found." << std::endl);
1018  }
1019  break;
1020  }
1021 
1022  default:
1023  libmesh_error_msg("Unrecognized ElemType: " << Utility::enum_to_string(elem->type()) << std::endl);
1024  }
1025  }
1026 
1027  // Index of the current edge
1028  unsigned current_edge = 0;
1029 
1030  const unsigned short n_nodes = elem->n_nodes();
1031 
1032  while (current_edge < n_edges)
1033  {
1034  // Find the edge the node is on
1035  bool found_edge = false;
1036  for (; current_edge<n_edges; ++current_edge)
1037  if (elem->is_node_on_edge(local_node_number, current_edge))
1038  {
1039  found_edge = true;
1040  break;
1041  }
1042 
1043  // Did we find one?
1044  if (found_edge)
1045  {
1046  const Node * node_to_save = nullptr;
1047 
1048  // Find another node in this element on this edge
1049  for (unsigned other_node_this_edge = 0; other_node_this_edge != n_nodes; other_node_this_edge++)
1050  if ( (elem->is_node_on_edge(other_node_this_edge, current_edge)) && // On the current edge
1051  (elem->node_id(other_node_this_edge) != global_id)) // But not the original node
1052  {
1053  // We've found a nodal neighbor! Save a pointer to it..
1054  node_to_save = elem->node_ptr(other_node_this_edge);
1055  break;
1056  }
1057 
1058  // Make sure we found something
1059  libmesh_assert(node_to_save != nullptr);
1060 
1061  neighbor_set.insert(node_to_save);
1062  }
1063 
1064  // Keep looking for edges, node may be on more than one edge
1065  current_edge++;
1066  }
1067  } // if (elem->active())
1068  } // for
1069 
1070  // Assign the entries from the set to the vector. Note: this
1071  // replaces any existing contents in neighbors and modifies its size
1072  // accordingly.
1073  neighbors.assign(neighbor_set.begin(), neighbor_set.end());
1074 }

References libMesh::EDGE2, libMesh::EDGE3, libMesh::EDGE4, libMesh::Utility::enum_to_string(), libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::libmesh_assert(), and n_nodes.

◆ find_nodal_neighbors() [2/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 743 of file mesh_tools.C.

747 {
748  // We'll refer back to the Node ID several times
749  dof_id_type global_id = node.id();
750 
751  // We'll construct a std::set<const Node *> for more efficient
752  // searching while finding the nodal neighbors, and return it to the
753  // user in a std::vector.
754  std::set<const Node *> neighbor_set;
755 
756  // Look through the elements that contain this node
757  // find the local node id... then find the side that
758  // node lives on in the element
759  // next, look for the _other_ node on that side
760  // That other node is a "nodal_neighbor"... save it
761  for (const auto & elem : nodes_to_elem_map[global_id])
762  {
763  // We only care about active elements...
764  if (elem->active())
765  {
766  // Which local node number is global_id?
767  unsigned local_node_number = elem->local_node(global_id);
768 
769  // Make sure it was found
770  libmesh_assert_not_equal_to(local_node_number, libMesh::invalid_uint);
771 
772  const unsigned short n_edges = elem->n_edges();
773 
774  // If this element has no edges, the edge-based algorithm below doesn't make sense.
775  if (!n_edges)
776  {
777  switch (elem->type())
778  {
779  case EDGE2:
780  {
781  switch (local_node_number)
782  {
783  case 0:
784  // The other node is a nodal neighbor
785  neighbor_set.insert(elem->node_ptr(1));
786  break;
787 
788  case 1:
789  // The other node is a nodal neighbor
790  neighbor_set.insert(elem->node_ptr(0));
791  break;
792 
793  default:
794  libmesh_error_msg("Invalid local node number: " << local_node_number << " found." << std::endl);
795  }
796  break;
797  }
798 
799  case EDGE3:
800  {
801  switch (local_node_number)
802  {
803  // The outside nodes have node 2 as a neighbor
804  case 0:
805  case 1:
806  neighbor_set.insert(elem->node_ptr(2));
807  break;
808 
809  // The middle node has the outer nodes as neighbors
810  case 2:
811  neighbor_set.insert(elem->node_ptr(0));
812  neighbor_set.insert(elem->node_ptr(1));
813  break;
814 
815  default:
816  libmesh_error_msg("Invalid local node number: " << local_node_number << " found." << std::endl);
817  }
818  break;
819  }
820 
821  case EDGE4:
822  {
823  switch (local_node_number)
824  {
825  case 0:
826  // The left-middle node is a nodal neighbor
827  neighbor_set.insert(elem->node_ptr(2));
828  break;
829 
830  case 1:
831  // The right-middle node is a nodal neighbor
832  neighbor_set.insert(elem->node_ptr(3));
833  break;
834 
835  // The left-middle node
836  case 2:
837  neighbor_set.insert(elem->node_ptr(0));
838  neighbor_set.insert(elem->node_ptr(3));
839  break;
840 
841  // The right-middle node
842  case 3:
843  neighbor_set.insert(elem->node_ptr(1));
844  neighbor_set.insert(elem->node_ptr(2));
845  break;
846 
847  default:
848  libmesh_error_msg("Invalid local node number: " << local_node_number << " found." << std::endl);
849  }
850  break;
851  }
852 
853  default:
854  libmesh_error_msg("Unrecognized ElemType: " << Utility::enum_to_string(elem->type()) << std::endl);
855  }
856  }
857 
858  // Index of the current edge
859  unsigned current_edge = 0;
860 
861  const unsigned short n_nodes = elem->n_nodes();
862 
863  while (current_edge < n_edges)
864  {
865  // Find the edge the node is on
866  bool found_edge = false;
867  for (; current_edge<n_edges; ++current_edge)
868  if (elem->is_node_on_edge(local_node_number, current_edge))
869  {
870  found_edge = true;
871  break;
872  }
873 
874  // Did we find one?
875  if (found_edge)
876  {
877  const Node * node_to_save = nullptr;
878 
879  // Find another node in this element on this edge
880  for (unsigned other_node_this_edge = 0; other_node_this_edge != n_nodes; other_node_this_edge++)
881  if ( (elem->is_node_on_edge(other_node_this_edge, current_edge)) && // On the current edge
882  (elem->node_id(other_node_this_edge) != global_id)) // But not the original node
883  {
884  // We've found a nodal neighbor! Save a pointer to it..
885  node_to_save = elem->node_ptr(other_node_this_edge);
886  break;
887  }
888 
889  // Make sure we found something
890  libmesh_assert(node_to_save != nullptr);
891 
892  neighbor_set.insert(node_to_save);
893  }
894 
895  // Keep looking for edges, node may be on more than one edge
896  current_edge++;
897  }
898  } // if (elem->active())
899  } // for
900 
901  // Assign the entries from the set to the vector. Note: this
902  // replaces any existing contents in neighbors and modifies its size
903  // accordingly.
904  neighbors.assign(neighbor_set.begin(), neighbor_set.end());
905 }

References libMesh::EDGE2, libMesh::EDGE3, libMesh::EDGE4, libMesh::Utility::enum_to_string(), libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::libmesh_assert(), and n_nodes.

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

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

696 {
697  for (const auto & elem : mesh.element_ptr_range())
698  if (!elem->subactive())
699  for (auto & n : elem->node_ref_range())
700  not_subactive_node_ids.insert(n.id());
701 }

References libMesh::MeshBase::element_ptr_range(), and mesh.

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

1962 {
1963  for (const auto & elem : mesh.active_element_ptr_range())
1964  for (auto & node : elem->node_ref_range())
1965  libmesh_assert_equal_to
1966  (node.processor_id(),
1967  node.choose_processor_id(node.processor_id(),
1968  elem->processor_id()));
1969 }

References libMesh::MeshBase::active_element_ptr_range(), and mesh.

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

1372 {
1373  LOG_SCOPE("libmesh_assert_connected_nodes()", "MeshTools");
1374 
1375  std::set<const Node *> used_nodes;
1376 
1377  for (const auto & elem : mesh.element_ptr_range())
1378  {
1379  libmesh_assert (elem);
1380 
1381  for (auto & n : elem->node_ref_range())
1382  used_nodes.insert(&n);
1383  }
1384 
1385  for (const auto & node : mesh.node_ptr_range())
1386  {
1387  libmesh_assert(node);
1388  libmesh_assert(used_nodes.count(node));
1389  }
1390 }

References libMesh::MeshBase::element_ptr_range(), libMesh::libmesh_assert(), mesh, and libMesh::MeshBase::node_ptr_range().

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

1665 {
1666  libmesh_parallel_only(mesh.comm());
1667 
1668  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
1669  mesh.comm().max(parallel_max_elem_id);
1670 
1671  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
1672  {
1673  const Elem * elem = mesh.query_elem_ptr(i);
1674  processor_id_type pid =
1675  elem ? elem->processor_id() : DofObject::invalid_processor_id;
1676  mesh.comm().min(pid);
1677  libmesh_assert(elem || pid != mesh.processor_id());
1678  }
1679 
1680  dof_id_type parallel_max_node_id = mesh.max_node_id();
1681  mesh.comm().max(parallel_max_node_id);
1682 
1683  for (dof_id_type i=0; i != parallel_max_node_id; ++i)
1684  {
1685  const Node * node = mesh.query_node_ptr(i);
1686  processor_id_type pid =
1687  node ? node->processor_id() : DofObject::invalid_processor_id;
1688  mesh.comm().min(pid);
1689  libmesh_assert(node || pid != mesh.processor_id());
1690  }
1691 }

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

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

1695 {
1696  libmesh_parallel_only(mesh.comm());
1697  auto locator = mesh.sub_point_locator();
1698 
1699  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
1700  mesh.comm().max(parallel_max_elem_id);
1701 
1702  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
1703  {
1704  const Elem * elem = mesh.query_elem_ptr(i);
1705 
1706  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
1707  unsigned int n_nodes = my_n_nodes;
1708  mesh.comm().max(n_nodes);
1709 
1710  if (n_nodes)
1711  libmesh_assert(mesh.comm().semiverify(elem ? &my_n_nodes : nullptr));
1712 
1713  for (unsigned int n=0; n != n_nodes; ++n)
1714  {
1715  const Node * node = elem ? elem->node_ptr(n) : nullptr;
1716  processor_id_type pid =
1717  node ? node->processor_id() : DofObject::invalid_processor_id;
1718  mesh.comm().min(pid);
1719  libmesh_assert(node || pid != mesh.processor_id());
1720  }
1721  }
1722 }

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

◆ 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 processors, as is required by libMesh numeric classes.

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

Definition at line 1593 of file mesh_tools.C.

1594 {
1595  LOG_SCOPE("libmesh_assert_contiguous_dof_ids()", "MeshTools");
1596 
1597  if (mesh.n_processors() == 1)
1598  return;
1599 
1600  libmesh_parallel_only(mesh.comm());
1601 
1602  dof_id_type min_dof_id = std::numeric_limits<dof_id_type>::max(),
1603  max_dof_id = std::numeric_limits<dof_id_type>::min();
1604 
1605  // Figure out what our local dof id range is
1606  for (const auto * node : mesh.local_node_ptr_range())
1607  {
1608  for (auto v : IntRange<unsigned int>(0, node->n_vars(sysnum)))
1609  for (auto c : IntRange<unsigned int>(0, node->n_comp(sysnum, v)))
1610  {
1611  dof_id_type id = node->dof_number(sysnum, v, c);
1612  min_dof_id = std::min (min_dof_id, id);
1613  max_dof_id = std::max (max_dof_id, id);
1614  }
1615  }
1616 
1617  // Make sure no other processors' ids are inside it
1618  for (const auto * node : mesh.node_ptr_range())
1619  {
1620  if (node->processor_id() == mesh.processor_id())
1621  continue;
1622  for (auto v : IntRange<unsigned int>(0, node->n_vars(sysnum)))
1623  for (auto c : IntRange<unsigned int>(0, node->n_comp(sysnum, v)))
1624  {
1625  dof_id_type id = node->dof_number(sysnum, v, c);
1626  libmesh_assert (id < min_dof_id ||
1627  id > max_dof_id);
1628  }
1629  }
1630 }

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::MeshBase::local_node_ptr_range(), mesh, libMesh::ParallelObject::n_processors(), libMesh::MeshBase::node_ptr_range(), and libMesh::ParallelObject::processor_id().

◆ libmesh_assert_equal_n_systems()

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

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

Definition at line 1168 of file mesh_tools.C.

1169 {
1170  LOG_SCOPE("libmesh_assert_equal_n_systems()", "MeshTools");
1171 
1172  unsigned int n_sys = libMesh::invalid_uint;
1173 
1174  for (const auto & elem : mesh.element_ptr_range())
1175  {
1176  if (n_sys == libMesh::invalid_uint)
1177  n_sys = elem->n_systems();
1178  else
1179  libmesh_assert_equal_to (elem->n_systems(), n_sys);
1180  }
1181 
1182  for (const auto & node : mesh.node_ptr_range())
1183  {
1184  if (n_sys == libMesh::invalid_uint)
1185  n_sys = node->n_systems();
1186  else
1187  libmesh_assert_equal_to (node->n_systems(), n_sys);
1188  }
1189 }

References libMesh::MeshBase::element_ptr_range(), libMesh::invalid_uint, mesh, and libMesh::MeshBase::node_ptr_range().

◆ libmesh_assert_no_links_to_elem()

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

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

Definition at line 1272 of file mesh_tools.C.

1274 {
1275  for (const auto & elem : mesh.element_ptr_range())
1276  {
1277  libmesh_assert (elem);
1278  libmesh_assert_not_equal_to (elem->parent(), bad_elem);
1279  for (auto n : elem->neighbor_ptr_range())
1280  libmesh_assert_not_equal_to (n, bad_elem);
1281 
1282 #ifdef LIBMESH_ENABLE_AMR
1283  if (elem->has_children())
1284  for (auto & child : elem->child_ref_range())
1285  libmesh_assert_not_equal_to (&child, bad_elem);
1286 #endif
1287  }
1288 }

References libMesh::MeshBase::element_ptr_range(), libMesh::libmesh_assert(), and mesh.

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

1195 {
1196  LOG_SCOPE("libmesh_assert_old_dof_objects()", "MeshTools");
1197 
1198  for (const auto & elem : mesh.element_ptr_range())
1199  {
1200  if (elem->refinement_flag() == Elem::JUST_REFINED ||
1201  elem->refinement_flag() == Elem::INACTIVE)
1202  continue;
1203 
1204  if (elem->has_dofs())
1205  libmesh_assert(elem->old_dof_object);
1206 
1207  for (auto & node : elem->node_ref_range())
1208  if (node.has_dofs())
1209  libmesh_assert(node.old_dof_object);
1210  }
1211 }

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

◆ 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 recieved consistent DofObject::id(), using element topology to identify matching nodes.

Definition at line 1870 of file mesh_tools.C.

1871 {
1872  LOG_SCOPE("libmesh_assert_parallel_consistent_new_node_procids()", "MeshTools");
1873 
1874  if (mesh.n_processors() == 1)
1875  return;
1876 
1877  libmesh_parallel_only(mesh.comm());
1878 
1879  // We want this test to hit every node when called even after nodes
1880  // have been added asynchronously but before everything has been
1881  // renumbered.
1882  dof_id_type parallel_max_elem_id = mesh.max_elem_id();
1883  mesh.comm().max(parallel_max_elem_id);
1884 
1885  std::vector<bool> elem_touched_by_anyone(parallel_max_elem_id, false);
1886 
1887  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
1888  {
1889  const Elem * elem = mesh.query_elem_ptr(i);
1890 
1891  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
1892  unsigned int n_nodes = my_n_nodes;
1893  mesh.comm().max(n_nodes);
1894 
1895  if (n_nodes)
1896  libmesh_assert(mesh.comm().semiverify(elem ? &my_n_nodes : nullptr));
1897 
1898  for (unsigned int n=0; n != n_nodes; ++n)
1899  {
1900  const Node * node = elem ? elem->node_ptr(n) : nullptr;
1901  const processor_id_type pid = node ? node->processor_id() : 0;
1902  libmesh_assert(mesh.comm().semiverify (node ? &pid : nullptr));
1903  }
1904  }
1905 }

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

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

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

1771 {
1772  LOG_SCOPE("libmesh_assert_parallel_consistent_procids()", "MeshTools");
1773 
1774  if (mesh.n_processors() == 1)
1775  return;
1776 
1777  libmesh_parallel_only(mesh.comm());
1778 
1779  // Some code (looking at you, stitch_meshes) modifies DofObject ids
1780  // without keeping max_elem_id()/max_node_id() consistent, but
1781  // that's done in a safe way for performance reasons, so we'll play
1782  // along and just figure out new max ids ourselves.
1783  dof_id_type parallel_max_elem_id = 0;
1784  for (const auto & elem : mesh.element_ptr_range())
1785  parallel_max_elem_id = std::max<dof_id_type>(parallel_max_elem_id,
1786  elem->id()+1);
1787  mesh.comm().max(parallel_max_elem_id);
1788 
1789  // Check processor ids for consistency between processors
1790 
1791  for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
1792  {
1793  const Elem * elem = mesh.query_elem_ptr(i);
1794 
1795  processor_id_type min_id =
1796  elem ? elem->processor_id() :
1797  std::numeric_limits<processor_id_type>::max();
1798  mesh.comm().min(min_id);
1799 
1800  processor_id_type max_id =
1801  elem ? elem->processor_id() :
1802  std::numeric_limits<processor_id_type>::min();
1803  mesh.comm().max(max_id);
1804 
1805  if (elem)
1806  {
1807  libmesh_assert_equal_to (min_id, elem->processor_id());
1808  libmesh_assert_equal_to (max_id, elem->processor_id());
1809  }
1810 
1811  if (min_id == mesh.processor_id())
1812  libmesh_assert(elem);
1813  }
1814 }

References libMesh::ParallelObject::comm(), libMesh::MeshBase::element_ptr_range(), libMesh::libmesh_assert(), mesh, libMesh::ParallelObject::n_processors(), libMesh::ParallelObject::processor_id(), libMesh::DofObject::processor_id(), and libMesh::MeshBase::query_elem_ptr().

◆ libmesh_assert_parallel_consistent_procids< Node >()

Definition at line 1908 of file mesh_tools.C.

1909 {
1910  LOG_SCOPE("libmesh_assert_parallel_consistent_procids()", "MeshTools");
1911 
1912  if (mesh.n_processors() == 1)
1913  return;
1914 
1915  libmesh_parallel_only(mesh.comm());
1916 
1917  // We want this test to be valid even when called even after nodes
1918  // have been added asynchronously but before they're renumbered
1919  //
1920  // Plus, some code (looking at you, stitch_meshes) modifies
1921  // DofObject ids without keeping max_elem_id()/max_node_id()
1922  // consistent, but that's done in a safe way for performance
1923  // reasons, so we'll play along and just figure out new max ids
1924  // ourselves.
1925  dof_id_type parallel_max_node_id = 0;
1926  for (const auto & node : mesh.node_ptr_range())
1927  parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
1928  node->id()+1);
1929  mesh.comm().max(parallel_max_node_id);
1930 
1931  std::vector<bool> node_touched_by_anyone(parallel_max_node_id, false);
1932 
1933  for (const auto & elem : as_range(mesh.local_elements_begin(),
1935  {
1936  libmesh_assert (elem);
1937 
1938  for (auto & node : elem->node_ref_range())
1939  {
1940  dof_id_type nodeid = node.id();
1941  node_touched_by_anyone[nodeid] = true;
1942  }
1943  }
1944  mesh.comm().max(node_touched_by_anyone);
1945 
1946  // Check processor ids for consistency between processors
1947  // on any node an element touches
1948  for (dof_id_type i=0; i != parallel_max_node_id; ++i)
1949  {
1950  if (!node_touched_by_anyone[i])
1951  continue;
1952 
1953  const Node * node = mesh.query_node_ptr(i);
1954  const processor_id_type pid = node ? node->processor_id() : 0;
1955 
1956  libmesh_assert(mesh.comm().semiverify (node ? &pid : nullptr));
1957  }
1958 }

References libMesh::as_range(), libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::MeshBase::local_elements_begin(), libMesh::MeshBase::local_elements_end(), mesh, libMesh::ParallelObject::n_processors(), libMesh::MeshBase::node_ptr_range(), libMesh::DofObject::processor_id(), and libMesh::MeshBase::query_node_ptr().

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

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

1727 {
1728  LOG_SCOPE("libmesh_assert_topology_consistent_procids()", "MeshTools");
1729 
1730  // This parameter is not used when !LIBMESH_ENABLE_AMR
1732 
1733  // If we're adaptively refining, check processor ids for consistency
1734  // between parents and children.
1735 #ifdef LIBMESH_ENABLE_AMR
1736 
1737  // Ancestor elements we won't worry about, but subactive and active
1738  // elements ought to have parents with consistent processor ids
1739  for (const auto & elem : mesh.element_ptr_range())
1740  {
1741  libmesh_assert(elem);
1742 
1743  if (!elem->active() && !elem->subactive())
1744  continue;
1745 
1746  const Elem * parent = elem->parent();
1747 
1748  if (parent)
1749  {
1750  libmesh_assert(parent->has_children());
1751  processor_id_type parent_procid = parent->processor_id();
1752  bool matching_child_id = false;
1753  // If we've got a remote_elem then we don't know whether
1754  // it's responsible for the parent's processor id; all
1755  // we can do is assume it is and let its processor fail
1756  // an assert if there's something wrong.
1757  for (auto & child : parent->child_ref_range())
1758  if (&child == remote_elem ||
1759  child.processor_id() == parent_procid)
1760  matching_child_id = true;
1761  libmesh_assert(matching_child_id);
1762  }
1763  }
1764 #endif
1765 }

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

◆ libmesh_assert_topology_consistent_procids< Node >()

Definition at line 1819 of file mesh_tools.C.

1820 {
1821  LOG_SCOPE("libmesh_assert_topology_consistent_procids()", "MeshTools");
1822 
1823  if (mesh.n_processors() == 1)
1824  return;
1825 
1826  libmesh_parallel_only(mesh.comm());
1827 
1828  // We want this test to be valid even when called even after nodes
1829  // have been added asynchronously but before they're renumbered.
1830  //
1831  // Plus, some code (looking at you, stitch_meshes) modifies
1832  // DofObject ids without keeping max_elem_id()/max_node_id()
1833  // consistent, but that's done in a safe way for performance
1834  // reasons, so we'll play along and just figure out new max ids
1835  // ourselves.
1836  dof_id_type parallel_max_node_id = 0;
1837  for (const auto & node : mesh.node_ptr_range())
1838  parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
1839  node->id()+1);
1840  mesh.comm().max(parallel_max_node_id);
1841 
1842 
1843  std::vector<bool> node_touched_by_me(parallel_max_node_id, false);
1844 
1845  for (const auto & elem : as_range(mesh.local_elements_begin(),
1847  {
1848  libmesh_assert (elem);
1849 
1850  for (auto & node : elem->node_ref_range())
1851  {
1852  dof_id_type nodeid = node.id();
1853  node_touched_by_me[nodeid] = true;
1854  }
1855  }
1856  std::vector<bool> node_touched_by_anyone(node_touched_by_me);
1857  mesh.comm().max(node_touched_by_anyone);
1858 
1859  for (const auto & node : mesh.local_node_ptr_range())
1860  {
1861  libmesh_assert(node);
1862  dof_id_type nodeid = node->id();
1863  libmesh_assert(!node_touched_by_anyone[nodeid] ||
1864  node_touched_by_me[nodeid]);
1865  }
1866 }

References libMesh::as_range(), libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::MeshBase::local_elements_begin(), libMesh::MeshBase::local_elements_end(), libMesh::MeshBase::local_node_ptr_range(), mesh, libMesh::ParallelObject::n_processors(), and libMesh::MeshBase::node_ptr_range().

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

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

1316 {
1317  LOG_SCOPE("libmesh_assert_valid_amr_elem_ids()", "MeshTools");
1318 
1319  for (const auto & elem : mesh.element_ptr_range())
1320  {
1321  libmesh_assert (elem);
1322 
1323  const Elem * parent = elem->parent();
1324 
1325  if (parent)
1326  {
1327  libmesh_assert_greater_equal (elem->id(), parent->id());
1328  libmesh_assert_greater_equal (elem->processor_id(), parent->processor_id());
1329  }
1330  }
1331 }

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

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

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

1336 {
1337  LOG_SCOPE("libmesh_assert_valid_amr_interior_parents()", "MeshTools");
1338 
1339  for (const auto & elem : mesh.element_ptr_range())
1340  {
1341  libmesh_assert (elem);
1342 
1343  // We can skip to the next element if we're full-dimension
1344  // and therefore don't have any interior parents
1345  if (elem->dim() >= LIBMESH_DIM)
1346  continue;
1347 
1348  const Elem * ip = elem->interior_parent();
1349 
1350  const Elem * parent = elem->parent();
1351 
1352  if (ip && (ip != remote_elem) && parent)
1353  {
1354  libmesh_assert_equal_to (ip->top_parent(),
1355  elem->top_parent()->interior_parent());
1356 
1357  if (ip->level() == elem->level())
1358  libmesh_assert_equal_to (ip->parent(),
1359  parent->interior_parent());
1360  else
1361  {
1362  libmesh_assert_less (ip->level(), elem->level());
1363  libmesh_assert_equal_to (ip, parent->interior_parent());
1364  }
1365  }
1366  }
1367 }

References libMesh::MeshBase::element_ptr_range(), 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().

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

1397 {
1398  LOG_SCOPE("libmesh_assert_valid_boundary_ids()", "MeshTools");
1399 
1400  if (mesh.n_processors() == 1)
1401  return;
1402 
1403  libmesh_parallel_only(mesh.comm());
1404 
1405  const BoundaryInfo & boundary_info = mesh.get_boundary_info();
1406 
1407  dof_id_type pmax_elem_id = mesh.max_elem_id();
1408  mesh.comm().max(pmax_elem_id);
1409 
1410  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1411  {
1412  const Elem * elem = mesh.query_elem_ptr(i);
1413  const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
1414  const unsigned int my_n_edges = elem ? elem->n_edges() : 0;
1415  const unsigned int my_n_sides = elem ? elem->n_sides() : 0;
1416  unsigned int
1417  n_nodes = my_n_nodes,
1418  n_edges = my_n_edges,
1419  n_sides = my_n_sides;
1420 
1421  mesh.comm().max(n_nodes);
1422  mesh.comm().max(n_edges);
1423  mesh.comm().max(n_sides);
1424 
1425  if (elem)
1426  {
1427  libmesh_assert_equal_to(my_n_nodes, n_nodes);
1428  libmesh_assert_equal_to(my_n_edges, n_edges);
1429  libmesh_assert_equal_to(my_n_sides, n_sides);
1430  }
1431 
1432  // Let's test all IDs on the element with one communication
1433  // rather than n_nodes + n_edges + n_sides communications, to
1434  // cut down on latency in dbg modes.
1435  std::vector<boundary_id_type> all_bcids;
1436 
1437  for (unsigned int n=0; n != n_nodes; ++n)
1438  {
1439  std::vector<boundary_id_type> bcids;
1440  if (elem)
1441  {
1442  boundary_info.boundary_ids(elem->node_ptr(n), bcids);
1443 
1444  // Ordering of boundary ids shouldn't matter
1445  std::sort(bcids.begin(), bcids.end());
1446  }
1447  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1448 
1449  all_bcids.insert(all_bcids.end(), bcids.begin(),
1450  bcids.end());
1451  // Separator
1452  all_bcids.push_back(BoundaryInfo::invalid_id);
1453  }
1454 
1455  for (unsigned short e=0; e != n_edges; ++e)
1456  {
1457  std::vector<boundary_id_type> bcids;
1458 
1459  if (elem)
1460  {
1461  boundary_info.edge_boundary_ids(elem, e, bcids);
1462 
1463  // Ordering of boundary ids shouldn't matter
1464  std::sort(bcids.begin(), bcids.end());
1465  }
1466 
1467  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1468 
1469  all_bcids.insert(all_bcids.end(), bcids.begin(),
1470  bcids.end());
1471  // Separator
1472  all_bcids.push_back(BoundaryInfo::invalid_id);
1473 
1474  if (elem)
1475  {
1476  boundary_info.raw_edge_boundary_ids(elem, e, bcids);
1477 
1478  // Ordering of boundary ids shouldn't matter
1479  std::sort(bcids.begin(), bcids.end());
1480 
1481  all_bcids.insert(all_bcids.end(), bcids.begin(),
1482  bcids.end());
1483  // Separator
1484  all_bcids.push_back(BoundaryInfo::invalid_id);
1485  }
1486 
1487  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1488  }
1489 
1490  for (unsigned short s=0; s != n_sides; ++s)
1491  {
1492  std::vector<boundary_id_type> bcids;
1493 
1494  if (elem)
1495  {
1496  boundary_info.boundary_ids(elem, s, bcids);
1497 
1498  // Ordering of boundary ids shouldn't matter
1499  std::sort(bcids.begin(), bcids.end());
1500 
1501  all_bcids.insert(all_bcids.end(), bcids.begin(),
1502  bcids.end());
1503  // Separator
1504  all_bcids.push_back(BoundaryInfo::invalid_id);
1505  }
1506 
1507  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1508 
1509  if (elem)
1510  {
1511  boundary_info.raw_boundary_ids(elem, s, bcids);
1512 
1513  // Ordering of boundary ids shouldn't matter
1514  std::sort(bcids.begin(), bcids.end());
1515 
1516  all_bcids.insert(all_bcids.end(), bcids.begin(),
1517  bcids.end());
1518  // Separator
1519  all_bcids.push_back(BoundaryInfo::invalid_id);
1520  }
1521 
1522  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1523  }
1524 
1525  for (unsigned short sf=0; sf != 2; ++sf)
1526  {
1527  std::vector<boundary_id_type> bcids;
1528 
1529  if (elem)
1530  {
1531  boundary_info.shellface_boundary_ids(elem, sf, bcids);
1532 
1533  // Ordering of boundary ids shouldn't matter
1534  std::sort(bcids.begin(), bcids.end());
1535 
1536  all_bcids.insert(all_bcids.end(), bcids.begin(),
1537  bcids.end());
1538  // Separator
1539  all_bcids.push_back(BoundaryInfo::invalid_id);
1540  }
1541 
1542  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1543 
1544  if (elem)
1545  {
1546  boundary_info.raw_shellface_boundary_ids(elem, sf, bcids);
1547 
1548  // Ordering of boundary ids shouldn't matter
1549  std::sort(bcids.begin(), bcids.end());
1550 
1551  all_bcids.insert(all_bcids.end(), bcids.begin(),
1552  bcids.end());
1553  // Separator
1554  all_bcids.push_back(BoundaryInfo::invalid_id);
1555  }
1556 
1557  // libmesh_assert(mesh.comm().semiverify (elem ? &bcids : nullptr));
1558  }
1559 
1560  libmesh_assert(mesh.comm().semiverify
1561  (elem ? &all_bcids : nullptr));
1562  }
1563 }

References libMesh::ParallelObject::comm(), libMesh::MeshBase::get_boundary_info(), libMesh::BoundaryInfo::invalid_id, libMesh::libmesh_assert(), 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(), and libMesh::MeshBase::query_elem_ptr().

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

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

1567 {
1568  LOG_SCOPE("libmesh_assert_valid_dof_ids()", "MeshTools");
1569 
1570  if (mesh.n_processors() == 1)
1571  return;
1572 
1573  libmesh_parallel_only(mesh.comm());
1574 
1575  dof_id_type pmax_elem_id = mesh.max_elem_id();
1576  mesh.comm().max(pmax_elem_id);
1577 
1578  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1579  assert_semiverify_dofobj(mesh.comm(),
1580  mesh.query_elem_ptr(i),
1581  sysnum);
1582 
1583  dof_id_type pmax_node_id = mesh.max_node_id();
1584  mesh.comm().max(pmax_node_id);
1585 
1586  for (dof_id_type i=0; i != pmax_node_id; ++i)
1587  assert_semiverify_dofobj(mesh.comm(),
1588  mesh.query_node_ptr(i),
1589  sysnum);
1590 }

References libMesh::ParallelObject::comm(), 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().

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

1293 {
1294  LOG_SCOPE("libmesh_assert_valid_elem_ids()", "MeshTools");
1295 
1296  processor_id_type lastprocid = 0;
1297  dof_id_type lastelemid = 0;
1298 
1299  for (const auto & elem : mesh.active_element_ptr_range())
1300  {
1301  libmesh_assert (elem);
1302  processor_id_type elemprocid = elem->processor_id();
1303  dof_id_type elemid = elem->id();
1304 
1305  libmesh_assert_greater_equal (elemid, lastelemid);
1306  libmesh_assert_greater_equal (elemprocid, lastprocid);
1307 
1308  lastelemid = elemid;
1309  lastprocid = elemprocid;
1310  }
1311 }

References libMesh::MeshBase::active_element_ptr_range(), libMesh::libmesh_assert(), and mesh.

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

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

2063 {
2064  LOG_SCOPE("libmesh_assert_valid_neighbors()", "MeshTools");
2065 
2066  for (const auto & elem : mesh.element_ptr_range())
2067  {
2068  libmesh_assert (elem);
2069  elem->libmesh_assert_valid_neighbors();
2070  }
2071 
2072  if (mesh.n_processors() == 1)
2073  return;
2074 
2075  libmesh_parallel_only(mesh.comm());
2076 
2077  dof_id_type pmax_elem_id = mesh.max_elem_id();
2078  mesh.comm().max(pmax_elem_id);
2079 
2080  for (dof_id_type i=0; i != pmax_elem_id; ++i)
2081  {
2082  const Elem * elem = mesh.query_elem_ptr(i);
2083 
2084  const unsigned int my_n_neigh = elem ? elem->n_neighbors() : 0;
2085  unsigned int n_neigh = my_n_neigh;
2086  mesh.comm().max(n_neigh);
2087  if (elem)
2088  libmesh_assert_equal_to (my_n_neigh, n_neigh);
2089 
2090  for (unsigned int n = 0; n != n_neigh; ++n)
2091  {
2092  dof_id_type my_neighbor = DofObject::invalid_id;
2093  dof_id_type * p_my_neighbor = nullptr;
2094 
2095  // If we have a non-remote_elem neighbor link, then we can
2096  // verify it.
2097  if (elem && elem->neighbor_ptr(n) != remote_elem)
2098  {
2099  p_my_neighbor = &my_neighbor;
2100  if (elem->neighbor_ptr(n))
2101  my_neighbor = elem->neighbor_ptr(n)->id();
2102 
2103  // But wait - if we haven't set remote_elem links yet then
2104  // some nullptr links on ghost elements might be
2105  // future-remote_elem links, so we can't verify those.
2106  if (!assert_valid_remote_elems &&
2107  !elem->neighbor_ptr(n) &&
2108  elem->processor_id() != mesh.processor_id())
2109  p_my_neighbor = nullptr;
2110  }
2111  libmesh_assert(mesh.comm().semiverify(p_my_neighbor));
2112  }
2113  }
2114 }

References libMesh::ParallelObject::comm(), libMesh::MeshBase::element_ptr_range(), libMesh::DofObject::id(), libMesh::DofObject::invalid_id, libMesh::libmesh_assert(), 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(), and libMesh::remote_elem.

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

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

1219 {
1220  LOG_SCOPE("libmesh_assert_valid_node_pointers()", "MeshTools");
1221 
1222  // Here we specifically do not want "auto &" because we need to
1223  // reseat the (temporary) pointer variable in the loop below,
1224  // without modifying the original.
1225  for (const Elem * elem : mesh.element_ptr_range())
1226  {
1227  libmesh_assert (elem);
1228  while (elem)
1229  {
1230  elem->libmesh_assert_valid_node_pointers();
1231  for (auto n : elem->neighbor_ptr_range())
1232  if (n && n != remote_elem)
1233  n->libmesh_assert_valid_node_pointers();
1234 
1235  libmesh_assert_not_equal_to (elem->parent(), remote_elem);
1236  elem = elem->parent();
1237  }
1238  }
1239 }

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

◆ 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 581 of file mesh_tools.h.

581  {
582  libmesh_assert_parallel_consistent_procids<DofObjectSubclass>(mesh);
583  libmesh_assert_topology_consistent_procids<DofObjectSubclass>(mesh);
584 }

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

1979 {
1980  LOG_SCOPE("libmesh_assert_valid_refinement_flags()", "MeshTools");
1981 
1982  libmesh_parallel_only(mesh.comm());
1983  if (mesh.n_processors() == 1)
1984  return;
1985 
1986  dof_id_type pmax_elem_id = mesh.max_elem_id();
1987  mesh.comm().max(pmax_elem_id);
1988 
1989  std::vector<unsigned char> my_elem_h_state(pmax_elem_id, 255);
1990  std::vector<unsigned char> my_elem_p_state(pmax_elem_id, 255);
1991 
1992  for (const auto & elem : mesh.element_ptr_range())
1993  {
1994  libmesh_assert (elem);
1995  dof_id_type elemid = elem->id();
1996 
1997  my_elem_h_state[elemid] =
1998  static_cast<unsigned char>(elem->refinement_flag());
1999 
2000  my_elem_p_state[elemid] =
2001  static_cast<unsigned char>(elem->p_refinement_flag());
2002  }
2003  std::vector<unsigned char> min_elem_h_state(my_elem_h_state);
2004  mesh.comm().min(min_elem_h_state);
2005 
2006  std::vector<unsigned char> min_elem_p_state(my_elem_p_state);
2007  mesh.comm().min(min_elem_p_state);
2008 
2009  for (dof_id_type i=0; i!= pmax_elem_id; ++i)
2010  {
2011  libmesh_assert(my_elem_h_state[i] == 255 ||
2012  my_elem_h_state[i] == min_elem_h_state[i]);
2013  libmesh_assert(my_elem_p_state[i] == 255 ||
2014  my_elem_p_state[i] == min_elem_p_state[i]);
2015  }
2016 }

References libMesh::ParallelObject::comm(), libMesh::MeshBase::element_ptr_range(), libMesh::libmesh_assert(), libMesh::MeshBase::max_elem_id(), mesh, and libMesh::ParallelObject::n_processors().

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

2027 {
2028  LOG_SCOPE("libmesh_assert_valid_refinement_tree()", "MeshTools");
2029 
2030  for (const auto & elem : mesh.element_ptr_range())
2031  {
2032  libmesh_assert(elem);
2033  if (elem->has_children())
2034  for (auto & child : elem->child_ref_range())
2035  if (&child != remote_elem)
2036  libmesh_assert_equal_to (child.parent(), elem);
2037  if (elem->active())
2038  {
2039  libmesh_assert(!elem->ancestor());
2040  libmesh_assert(!elem->subactive());
2041  }
2042  else if (elem->ancestor())
2043  {
2044  libmesh_assert(!elem->subactive());
2045  }
2046  else
2047  libmesh_assert(elem->subactive());
2048 
2049  if (elem->p_refinement_flag() == Elem::JUST_REFINED)
2050  libmesh_assert_greater(elem->p_level(), 0);
2051  }
2052 }

References libMesh::MeshBase::element_ptr_range(), 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().

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

1243 {
1244  LOG_SCOPE("libmesh_assert_valid_remote_elems()", "MeshTools");
1245 
1246  for (const auto & elem : as_range(mesh.local_elements_begin(),
1248  {
1249  libmesh_assert (elem);
1250 
1251  // We currently don't allow active_local_elements to have
1252  // remote_elem neighbors
1253  if (elem->active())
1254  for (auto n : elem->neighbor_ptr_range())
1255  libmesh_assert_not_equal_to (n, remote_elem);
1256 
1257 #ifdef LIBMESH_ENABLE_AMR
1258  const Elem * parent = elem->parent();
1259  if (parent)
1260  libmesh_assert_not_equal_to (parent, remote_elem);
1261 
1262  // We can only be strict about active elements' subactive
1263  // children
1264  if (elem->active() && elem->has_children())
1265  for (auto & child : elem->child_ref_range())
1266  libmesh_assert_not_equal_to (&child, remote_elem);
1267 #endif
1268  }
1269 }

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

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

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

1635 {
1636  LOG_SCOPE("libmesh_assert_valid_unique_ids()", "MeshTools");
1637 
1638  libmesh_parallel_only(mesh.comm());
1639 
1640  dof_id_type pmax_elem_id = mesh.max_elem_id();
1641  mesh.comm().max(pmax_elem_id);
1642 
1643  for (dof_id_type i=0; i != pmax_elem_id; ++i)
1644  {
1645  const Elem * elem = mesh.query_elem_ptr(i);
1646  const unique_id_type unique_id = elem ? elem->unique_id() : 0;
1647  const unique_id_type * uid_ptr = elem ? &unique_id : nullptr;
1648  libmesh_assert(mesh.comm().semiverify(uid_ptr));
1649  }
1650 
1651  dof_id_type pmax_node_id = mesh.max_node_id();
1652  mesh.comm().max(pmax_node_id);
1653 
1654  for (dof_id_type i=0; i != pmax_node_id; ++i)
1655  {
1656  const Node * node = mesh.query_node_ptr(i);
1657  const unique_id_type unique_id = node ? node->unique_id() : 0;
1658  const unique_id_type * uid_ptr = node ? &unique_id : nullptr;
1659  libmesh_assert(mesh.comm().semiverify(uid_ptr));
1660  }
1661 }

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::max_node_id(), mesh, libMesh::MeshBase::query_elem_ptr(), libMesh::MeshBase::query_node_ptr(), and libMesh::DofObject::unique_id().

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

◆ max_level()

unsigned int libMesh::MeshTools::max_level ( const MeshBase mesh)

Find the maximum h-refinement level in a mesh.

Referenced by libMesh::MeshRefinement::make_coarsening_compatible(), and libMesh::CheckpointIO::n_active_levels_in().

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

593 {
594  return static_cast<dof_id_type>(std::distance(mesh.active_type_elements_begin(type),
596 }

References libMesh::MeshBase::active_type_elements_begin(), libMesh::MeshBase::active_type_elements_end(), distance(), and mesh.

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

627 {
628  libmesh_parallel_only(mesh.comm());
629 
630  unsigned int nl = MeshTools::n_active_local_levels(mesh);
631 
632  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
634  if (elem->active())
635  nl = std::max(elem->level() + 1, nl);
636 
637  mesh.comm().max(nl);
638  return nl;
639 }

References libMesh::as_range(), libMesh::ParallelObject::comm(), mesh, n_active_local_levels(), libMesh::MeshBase::unpartitioned_elements_begin(), and libMesh::MeshBase::unpartitioned_elements_end().

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

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

615 {
616  unsigned int nl = 0;
617 
618  for (auto & elem : mesh.active_local_element_ptr_range())
619  nl = std::max(elem->level() + 1, nl);
620 
621  return nl;
622 }

References libMesh::MeshBase::active_local_element_ptr_range(), and mesh.

Referenced by n_active_levels().

◆ n_elem()

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

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

584 {
585  return static_cast<dof_id_type>(std::distance(mesh.type_elements_begin(type),
586  mesh.type_elements_end (type)));
587 }

References distance(), mesh, libMesh::MeshBase::type_elements_begin(), and libMesh::MeshBase::type_elements_end().

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

657 {
658  libmesh_parallel_only(mesh.comm());
659 
660  unsigned int nl = MeshTools::n_local_levels(mesh);
661 
662  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
664  nl = std::max(elem->level() + 1, nl);
665 
666  mesh.comm().max(nl);
667 
668  // n_levels() is only valid and should only be called in cases where
669  // the mesh is validly distributed (or serialized). Let's run an
670  // expensive test in debug mode to make sure this is such a case.
671 #ifdef DEBUG
672  const unsigned int paranoid_nl = MeshTools::paranoid_n_levels(mesh);
673  libmesh_assert_equal_to(nl, paranoid_nl);
674 #endif
675  return nl;
676 }

References libMesh::as_range(), libMesh::ParallelObject::comm(), mesh, n_local_levels(), paranoid_n_levels(), libMesh::MeshBase::unpartitioned_elements_begin(), and libMesh::MeshBase::unpartitioned_elements_end().

Referenced by libMesh::MeshCommunication::delete_remote_elements(), libMesh::UnstructuredMesh::find_neighbors(), libMesh::PetscDMWrapper::init_and_attach_petscdm(), libMesh::PetscDMWrapper::init_dm_data(), and libMesh::MeshTools::Modification::smooth().

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

644 {
645  unsigned int nl = 0;
646 
647  for (const auto & elem : as_range(mesh.local_elements_begin(),
649  nl = std::max(elem->level() + 1, nl);
650 
651  return nl;
652 }

References libMesh::as_range(), libMesh::MeshBase::local_elements_begin(), libMesh::MeshBase::local_elements_end(), and mesh.

Referenced by n_levels().

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

715 {
716  return cast_int<dof_id_type>(std::distance(begin, end));
717 }

References distance(), and end.

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

◆ 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.

Definition at line 598 of file mesh_tools.C.

601 {
602  dof_id_type cnt = 0;
603 
604  // iterate over the elements of the specified type
605  for (const auto & elem : as_range(mesh.type_elements_begin(type),
606  mesh.type_elements_end(type)))
607  if ((elem->level() == level) && !elem->subactive())
608  cnt++;
609 
610  return cnt;
611 }

References libMesh::as_range(), mesh, libMesh::MeshBase::type_elements_begin(), and libMesh::MeshBase::type_elements_end().

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

722 {
723  libmesh_parallel_only(mesh.comm());
724 
725  unsigned int max_p_level = 0;
726 
727  // first my local elements
728  for (const auto & elem : as_range(mesh.local_elements_begin(),
730  max_p_level = std::max(elem->p_level(), max_p_level);
731 
732  // then any unpartitioned objects
733  for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
735  max_p_level = std::max(elem->p_level(), max_p_level);
736 
737  mesh.comm().max(max_p_level);
738  return max_p_level + 1;
739 }

References libMesh::as_range(), libMesh::ParallelObject::comm(), libMesh::MeshBase::local_elements_begin(), libMesh::MeshBase::local_elements_end(), mesh, libMesh::MeshBase::unpartitioned_elements_begin(), and libMesh::MeshBase::unpartitioned_elements_end().

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

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

681 {
682  libmesh_parallel_only(mesh.comm());
683 
684  unsigned int nl = 0;
685  for (const auto & elem : mesh.element_ptr_range())
686  nl = std::max(elem->level() + 1, nl);
687 
688  mesh.comm().max(nl);
689  return nl;
690 }

References libMesh::ParallelObject::comm(), libMesh::MeshBase::element_ptr_range(), and mesh.

Referenced by n_levels().

◆ processor_bounding_box()

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

Definition at line 469 of file mesh_tools.C.

471 {
472  libmesh_deprecated();
474 }

References create_processor_bounding_box(), and mesh.

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

507 {
508  libMesh::BoundingBox bbox =
510 
511  const Real diag = (bbox.second - bbox.first).norm();
512  const Point cent = (bbox.second + bbox.first)/2;
513 
514  return Sphere (cent, .5*diag);
515 }

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

◆ subdomain_bounding_box()

MeshTools::BoundingBox libMesh::MeshTools::subdomain_bounding_box ( const MeshBase mesh,
const subdomain_id_type  sid 
)
Returns
Two points defining a Cartesian box that bounds the elements belonging to subdomain sid.

Definition at line 521 of file mesh_tools.C.

523 {
524  libmesh_deprecated();
526 }

References create_subdomain_bounding_box(), and mesh.

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

558 {
559  libMesh::BoundingBox bbox =
561 
562  const Real diag = (bbox.second - bbox.first).norm();
563  const Point cent = (bbox.second + bbox.first)/2;
564 
565  return Sphere (cent, .5*diag);
566 }

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

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

214 {
215  if (!mesh.is_serial())
216  {
217  libmesh_parallel_only(mesh.comm());
219  mesh.comm().sum(weight);
220  dof_id_type unpartitioned_weight =
221  MeshTools::weight (mesh, DofObject::invalid_processor_id);
222  return weight + unpartitioned_weight;
223  }
224 
225  SumElemWeight sew;
226 
228  mesh.elements_end()),
229  sew);
230  return sew.weight();
231 
232 }

References libMesh::ParallelObject::comm(), libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), libMesh::DofObject::invalid_processor_id, libMesh::MeshBase::is_serial(), mesh, libMesh::Threads::parallel_reduce(), libMesh::ParallelObject::processor_id(), and weight().

◆ weight() [1/2]

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

Definition at line 113 of file mesh_tools.h.

114 { return MeshTools::weight (mesh, mesh.processor_id()); }

References mesh, and weight().

◆ weight() [2/2]

dof_id_type libMesh::MeshTools::weight ( const MeshBase mesh,
const processor_id_type  pid 
)
libMesh::MeshBase::pid_elements_begin
virtual element_iterator pid_elements_begin(processor_id_type proc_id)=0
Iterate over all elements with a specified processor id.
libMesh::MeshBase::active_local_subdomain_elements_end
virtual element_iterator active_local_subdomain_elements_end(subdomain_id_type subdomain_id)=0
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::BoundaryInfo
The BoundaryInfo class contains information relevant to boundary conditions including storing faces,...
Definition: boundary_info.h:57
libMesh::Elem::is_node_on_side
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
libMesh::Elem::n_edges
virtual unsigned int n_edges() const =0
libMesh::invalid_uint
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:249
libMesh::MeshTools::n_local_levels
unsigned int n_local_levels(const MeshBase &mesh)
Definition: mesh_tools.C:643
libMesh::MeshTools::paranoid_n_levels
unsigned int paranoid_n_levels(const MeshBase &mesh)
Definition: mesh_tools.C:680
libMesh::MeshTools::n_elem
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:705
libMesh::unique_id_type
uint8_t unique_id_type
Definition: id_types.h:86
libMesh::MeshBase::get_boundary_info
const BoundaryInfo & get_boundary_info() const
The information about boundary ids on the mesh.
Definition: mesh_base.h:132
libMesh::MeshBase::is_serial
virtual bool is_serial() const
Definition: mesh_base.h:159
libMesh::Elem::level
unsigned int level() const
Definition: elem.h:2478
libMesh::Elem::child_ref_range
SimpleRange< ChildRefIter > child_ref_range()
Returns a range with all children of a parent element, usable in range-based for loops.
Definition: elem.h:1839
libMesh::Elem::n_nodes
virtual unsigned int n_nodes() const =0
libMesh::EDGE4
Definition: enum_elem_type.h:37
libMesh::MeshBase::active_local_element_ptr_range
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
libMesh::Elem::n_neighbors
unsigned int n_neighbors() const
Definition: elem.h:631
libMesh::MeshBase::pid_elements_end
virtual element_iterator pid_elements_end(processor_id_type proc_id)=0
libMesh::BoundingBox
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
libMesh::MeshBase::local_nodes_begin
virtual node_iterator local_nodes_begin()=0
Iterate over local nodes (nodes whose processor_id() matches the current processor).
mesh
MeshBase & mesh
Definition: mesh_tools.C:2137
libMesh::MeshBase::active_element_ptr_range
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
libMesh::MeshBase::n_elem
virtual dof_id_type n_elem() const =0
libMesh::MeshBase::max_elem_id
virtual dof_id_type max_elem_id() const =0
libMesh::MeshTools::create_subdomain_bounding_box
libMesh::BoundingBox create_subdomain_bounding_box(const MeshBase &mesh, const subdomain_id_type sid)
The same functionality as the deprecated MeshTools::subdomain_bounding_box().
Definition: mesh_tools.C:532
libMesh::MeshBase::type_elements_end
virtual element_iterator type_elements_end(ElemType type)=0
end
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end.
Definition: variant_filter_iterator.h:343
libMesh::ParallelObject::comm
const Parallel::Communicator & comm() const
Definition: parallel_object.h:94
libMesh::MeshTools::create_local_bounding_box
libMesh::BoundingBox create_local_bounding_box(const MeshBase &mesh)
Definition: mesh_tools.C:454
mesh
MeshBase & mesh
Definition: mesh_communication.C:1257
libMesh::MeshBase::max_node_id
virtual dof_id_type max_node_id() const =0
libMesh::DofObject::processor_id
processor_id_type processor_id() const
Definition: dof_object.h:829
libMesh::MeshBase::elements_begin
virtual element_iterator elements_begin()=0
Iterate over all the elements in the Mesh.
libMesh::MeshBase::pid_nodes_begin
virtual node_iterator pid_nodes_begin(processor_id_type proc_id)=0
Iterate over nodes with processor_id() == proc_id.
libMesh::MeshBase::type_elements_begin
virtual element_iterator type_elements_begin(ElemType type)=0
Iterate over all elements with a specified geometric type.
libMesh::MeshBase::local_elements_begin
virtual element_iterator local_elements_begin()=0
libMesh::MeshBase::query_elem_ptr
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0
libMesh::Sphere
This class defines a sphere.
Definition: sphere.h:72
libMesh::MeshBase::element_ptr_range
virtual SimpleRange< element_iterator > element_ptr_range()=0
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::IntRange
The IntRange templated class is intended to make it easy to loop over integers which are indices of a...
Definition: int_range.h:53
libMesh::MeshTools::create_bounding_box
libMesh::BoundingBox create_bounding_box(const MeshBase &mesh)
The same functionality as the deprecated MeshTools::bounding_box().
Definition: mesh_tools.C:389
libMesh::MeshBase::active_type_elements_end
virtual element_iterator active_type_elements_end(ElemType type)=0
libMesh::ParallelObject::n_processors
processor_id_type n_processors() const
Definition: parallel_object.h:100
libMesh::MeshTools::weight
dof_id_type weight(const MeshBase &mesh)
Definition: mesh_tools.h:113
new_proc_ids
const proc_id_map_type & new_proc_ids
Definition: mesh_tools.C:2207
libMesh::MeshBase::node_ptr_range
virtual SimpleRange< node_iterator > node_ptr_range()=0
libMesh::ParallelObject::processor_id
processor_id_type processor_id() const
Definition: parallel_object.h:106
libMesh::libmesh_ignore
void libmesh_ignore(const Args &...)
Definition: libmesh_common.h:526
libMesh::MeshBase::local_node_ptr_range
virtual SimpleRange< node_iterator > local_node_ptr_range()=0
libMesh::MeshTools::create_processor_bounding_box
libMesh::BoundingBox create_processor_bounding_box(const MeshBase &mesh, const processor_id_type pid)
The same functionality as the deprecated MeshTools::processor_bounding_box().
Definition: mesh_tools.C:480
libMesh::QUAD4
Definition: enum_elem_type.h:41
libMesh::MeshBase::pid_nodes_end
virtual node_iterator pid_nodes_end(processor_id_type proc_id)=0
libMesh::Point
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
libMesh::processor_id_type
uint8_t processor_id_type
Definition: id_types.h:104
libMesh::Node::choose_processor_id
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
libMesh::Node
A Node is like a Point, but with more information.
Definition: node.h:52
libMesh::Threads::parallel_reduce
void parallel_reduce(const Range &range, Body &body)
Execute the provided reduction operation in parallel on the specified range.
Definition: threads_none.h:101
libMesh::as_range
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.
Definition: simple_range.h:57
n_nodes
const dof_id_type n_nodes
Definition: tecplot_io.C:68
libMesh::DofObject::unique_id
unique_id_type unique_id() const
Definition: dof_object.h:784
libMesh::Utility::enum_to_string
std::string enum_to_string(const T e)
libMesh::MeshBase::nodes_end
virtual node_iterator nodes_end()=0
libMesh::MeshBase::skip_noncritical_partitioning
void skip_noncritical_partitioning(bool skip)
If true is passed in then the elements on this mesh will no longer be (re)partitioned,...
Definition: mesh_base.h:1058
libMesh::MeshTools::n_active_local_levels
unsigned int n_active_local_levels(const MeshBase &mesh)
Definition: mesh_tools.C:614
libMesh::MeshBase::node_ref
virtual const Node & node_ref(const dof_id_type i) const
Definition: mesh_base.h:451
libMesh::Elem::parent
const Elem * parent() const
Definition: elem.h:2434
libMesh::MeshBase::n_nodes
virtual dof_id_type n_nodes() const =0
distance
Real distance(const Point &p)
Definition: subdomains_ex3.C:50
libMesh::Elem::interior_parent
const Elem * interior_parent() const
Definition: elem.C:749
libMesh::Parallel::sync_dofobject_data_by_id
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.
Definition: parallel_ghost_sync.h:338
libMesh::MeshBase::sub_point_locator
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition: mesh_base.C:672
libMesh::MeshBase::nodes_begin
virtual node_iterator nodes_begin()=0
Iterate over all the nodes in the Mesh.
libMesh::MeshBase::active_type_elements_begin
virtual element_iterator active_type_elements_begin(ElemType type)=0
libMesh::MeshBase::local_elements_end
virtual element_iterator local_elements_end()=0
libMesh::DofObject::id
dof_id_type id() const
Definition: dof_object.h:767
libMesh::MeshBase::elements_end
virtual element_iterator elements_end()=0
libMesh::EDGE3
Definition: enum_elem_type.h:36
libMesh::Elem::has_children
bool has_children() const
Definition: elem.h:2383
libMesh::StoredRange
The StoredRange class defines a contiguous, divisible set of objects.
Definition: stored_range.h:52
libMesh::Elem
This is the base class from which all geometric element types are derived.
Definition: elem.h:100
std::norm
MetaPhysicL::DualNumber< T, D > norm(const MetaPhysicL::DualNumber< T, D > &in)
data
IterBase * data
Ideally this private member data should have protected access.
Definition: variant_filter_iterator.h:337
libMesh::Elem::neighbor_ptr
const Elem * neighbor_ptr(unsigned int i) const
Definition: elem.h:2085
libMesh::Elem::node_id
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1977
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::Elem::n_sides
virtual unsigned int n_sides() const =0
libMesh::MeshBase::query_node_ptr
virtual const Node * query_node_ptr(const dof_id_type i) const =0
libMesh::MeshTools::weight
dof_id_type weight(const MeshBase &mesh, const processor_id_type pid)
Definition: mesh_tools.C:236
libMesh::Elem::node_ptr
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2009
libMesh::MeshBase::local_nodes_end
virtual node_iterator local_nodes_end()=0
libMesh::Elem::which_neighbor_am_i
unsigned int which_neighbor_am_i(const Elem *e) const
This function tells you which neighbor e is.
Definition: elem.h:2323
libMesh::remote_elem
const RemoteElem * remote_elem
Definition: remote_elem.C:57
libMesh::MeshBase::unpartitioned_elements_end
virtual element_iterator unpartitioned_elements_end()=0
libMesh::EDGE2
Definition: enum_elem_type.h:35
libMesh::MeshBase::unpartitioned_elements_begin
virtual element_iterator unpartitioned_elements_begin()=0
Iterate over unpartitioned elements in the Mesh.
libMesh::MeshBase::active_local_subdomain_elements_begin
virtual element_iterator active_local_subdomain_elements_begin(subdomain_id_type subdomain_id)=0
libMesh::Elem::top_parent
const Elem * top_parent() const
Definition: elem.h:2460
libMesh::MeshTools::libmesh_assert_parallel_consistent_procids< Node >
void libmesh_assert_parallel_consistent_procids< Node >(const MeshBase &mesh)
Definition: mesh_tools.C:1908