libMesh
Loading...
Searching...
No Matches
Namespaces | Classes | Functions
libMesh::MeshTools Namespace Reference

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

Namespaces

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

Classes

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

Functions

dof_id_type total_weight (const MeshBase &mesh)
 
dof_id_type weight (const MeshBase &mesh, const processor_id_type pid)
 
dof_id_type weight (const MeshBase &mesh)
 
void build_nodes_to_elem_map (const MeshBase &mesh, std::vector< std::vector< dof_id_type > > &nodes_to_elem_map)
 After calling this function the input vector nodes_to_elem_map will contain the node to element connectivity.
 
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.
 
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.
 
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.
 
std::unordered_set< dof_id_typefind_boundary_nodes (const MeshBase &mesh)
 Returns a std::set containing Node IDs for all of the boundary nodes.
 
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.
 
libMesh::BoundingBox create_bounding_box (const MeshBase &mesh)
 
Sphere bounding_sphere (const MeshBase &mesh)
 
libMesh::BoundingBox create_nodal_bounding_box (const MeshBase &mesh)
 
libMesh::BoundingBox create_local_bounding_box (const MeshBase &mesh)
 
libMesh::BoundingBox create_processor_bounding_box (const MeshBase &mesh, const processor_id_type pid)
 
Sphere processor_bounding_sphere (const MeshBase &mesh, const processor_id_type pid)
 
libMesh::BoundingBox create_subdomain_bounding_box (const MeshBase &mesh, const subdomain_id_type sid)
 
Sphere subdomain_bounding_sphere (const MeshBase &mesh, const subdomain_id_type sid)
 
void elem_types (const MeshBase &mesh, std::vector< ElemType > &et)
 Fills in a vector of all element types in the mesh.
 
dof_id_type n_elem_of_type (const MeshBase &mesh, const ElemType type)
 
dof_id_type n_active_elem_of_type (const MeshBase &mesh, const ElemType type)
 
dof_id_type n_non_subactive_elem_of_type_at_level (const MeshBase &mesh, const ElemType type, const unsigned int level)
 
unsigned int n_levels (const MeshBase &mesh)
 
unsigned int n_local_levels (const MeshBase &mesh)
 
unsigned int n_active_levels (const MeshBase &mesh)
 
unsigned int n_active_local_levels (const MeshBase &mesh)
 
unsigned int n_p_levels (const MeshBase &mesh)
 
unsigned int paranoid_n_levels (const MeshBase &mesh)
 
dof_id_type n_connected_components (const MeshBase &mesh, Real constraint_tol=0)
 
void get_not_subactive_node_ids (const MeshBase &mesh, std::set< dof_id_type > &not_subactive_node_ids)
 Builds a set of node IDs for nodes which belong to non-subactive elements.
 
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).
 
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).
 
Real volume (const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
 Find the total volume of a mesh (interpreting that as area for dim = 2, or total arc length for dim = 1, or number of NodeElem in the mesh for dim = 0).
 
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.
 
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.
 
void find_nodal_or_face_neighbors (const MeshBase &mesh, const Node &node, const std::unordered_map< dof_id_type, std::vector< const Elem * > > &nodes_to_elem_map, std::vector< const Node * > &neighbors)
 Given a mesh and a node in the mesh, the vector will be filled with every node directly attached to the given one.
 
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.
 
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.
 
void clear_spline_nodes (MeshBase &)
 Remove spline node (for IsoGeometric Analysis meshes) elements and nodes and constraints from the mesh.
 
bool valid_is_prepared (const MeshBase &mesh)
 A function for testing whether a mesh's cached is_prepared() setting is not a false positive.
 
template<>
void libmesh_assert_topology_consistent_procids< Elem > (const MeshBase &mesh)
 
template<>
void libmesh_assert_topology_consistent_procids< Node > (const MeshBase &mesh)
 
template<>
void libmesh_assert_parallel_consistent_procids< Elem > (const MeshBase &mesh)
 
template<>
void libmesh_assert_parallel_consistent_procids< Node > (const MeshBase &mesh)
 
void libmesh_assert_equal_n_systems (const MeshBase &mesh)
 The following functions, only available in builds with NDEBUG undefined, are for asserting internal consistency that we hope should never be broken in opt.
 
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.
 
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.
 
void libmesh_assert_valid_remote_elems (const MeshBase &mesh)
 A function for verifying that active local elements' neighbors are never remote elements.
 
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)
 
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)
 
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)
 
void libmesh_assert_contiguous_dof_ids (const MeshBase &mesh, unsigned int sysnum)
 A function for verifying that degree of freedom indexes are contiguous on each processor, as is required by libMesh numeric classes.
 
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).
 
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()
 
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.
 
void libmesh_assert_no_links_to_elem (const MeshBase &mesh, const Elem *bad_elem)
 The following functions, only available in builds with DEBUG defined, typically have surprisingly slow asymptotic behavior, and so are unsuitable for use even with METHOD=devel.
 
void libmesh_assert_equal_points (const MeshBase &mesh)
 A function for testing that node locations match across processors.
 
void libmesh_assert_equal_connectivity (const MeshBase &mesh)
 A function for testing that element nodal connectivities match across processors.
 
void libmesh_assert_connected_nodes (const MeshBase &mesh)
 A function for verifying that all nodes are connected to at least one element.
 
void libmesh_assert_valid_constraint_rows (const MeshBase &mesh)
 A function for verifying that all mesh constraint rows express relations between nodes and elements that are semilocal (local or ghosted) to the current processor's portion of the mesh.
 
void libmesh_assert_valid_boundary_ids (const MeshBase &mesh)
 A function for verifying that boundary condition ids match across processors.
 
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.
 
void libmesh_assert_valid_unique_ids (const MeshBase &mesh)
 A function for verifying that unique ids match across processors.
 
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)
 
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.
 
void libmesh_assert_parallel_consistent_new_node_procids (const MeshBase &mesh)
 A function for verifying that processor assignment is parallel consistent (every processor agrees on the processor id of each node it can see) even on nodes which have not yet received consistent DofObject::id(), using element topology to identify matching nodes.
 
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)
 
template<typename DofObjectSubclass >
void libmesh_assert_valid_procids (const MeshBase &mesh)
 A function for verifying that processor assignment is both parallel and topologically consistent.
 
void libmesh_assert_valid_refinement_flags (const MeshBase &mesh)
 A function for verifying that refinement flags on elements are consistent between processors.
 
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)
 

Detailed Description

Utility functions for operations on a Mesh object.

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

Author
Benjamin S. Kirk
Date
2004

Function Documentation

◆ bounding_sphere()

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

Definition at line 618 of file mesh_tools.C.

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

References create_bounding_box(), mesh, 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 511 of file mesh_tools.C.

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

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

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

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

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

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

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

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

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

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

◆ clear_spline_nodes()

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

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

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

Definition at line 1221 of file mesh_tools.C.

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

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

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

◆ correct_node_proc_ids()

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

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

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

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

Definition at line 2508 of file mesh_tools.C.

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

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

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

◆ create_bounding_box()

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

Definition at line 566 of file mesh_tools.C.

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

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

Referenced by libMesh::Partitioner::_find_global_index_by_pid_map(), bounding_sphere(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::InfElemBuilder::build_inf_elem(), libMesh::MeshTetInterface::check_hull_integrity(), libMesh::MeshBase::get_info(), libMesh::PointLocatorTree::init(), libMesh::MetisPartitioner::partition_range(), libMesh::Partitioner::partition_unpartitioned_elements(), MeshGenerationTest::testBuildCube(), MeshGenerationTest::testBuildLine(), MeshGenerationTest::testBuildSquare(), 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 631 of file mesh_tools.C.

632{
633 FindBBox find_bbox;
634
635 Threads::parallel_reduce (ConstElemRange (mesh.local_elements_begin(),
636 mesh.local_elements_end()),
637 find_bbox);
638
639 return find_bbox.bbox();
640}

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

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

◆ create_nodal_bounding_box()

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

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

Definition at line 591 of file mesh_tools.C.

592{
593 // This function must be run on all processors at once
594 libmesh_parallel_only(mesh.comm());
595
596 FindBBox find_bbox;
597
598 // Start with any unpartitioned nodes we know about locally
601 find_bbox);
602
603 // Add our local nodes
604 Threads::parallel_reduce (ConstNodeRange (mesh.local_nodes_begin(),
605 mesh.local_nodes_end()),
606 find_bbox);
607
608 // Compare the bounding boxes across processors
609 mesh.comm().min(find_bbox.min());
610 mesh.comm().max(find_bbox.max());
611
612 return find_bbox.bbox();
613}

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

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

◆ create_processor_bounding_box()

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

Definition at line 645 of file mesh_tools.C.

647{
648 // This can only be run in parallel, with consistent arguments.
649 libmesh_parallel_only(mesh.comm());
651
652 libmesh_assert_less (pid, mesh.n_processors());
653
654 FindBBox find_bbox;
655
656 Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
657 mesh.pid_elements_end(pid)),
658 find_bbox);
659
660 // Compare the bounding boxes across processors
661 mesh.comm().min(find_bbox.min());
662 mesh.comm().max(find_bbox.max());
663
664 return find_bbox.bbox();
665}
timpi_pure bool verify(const T &r) const
processor_id_type n_processors() const

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

Referenced by processor_bounding_sphere().

◆ create_subdomain_bounding_box()

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

Definition at line 685 of file mesh_tools.C.

687{
688 // This can only be run in parallel, with consistent arguments.
689 libmesh_parallel_only(mesh.comm());
691
692 FindBBox find_bbox;
693
695 (ConstElemRange (mesh.active_local_subdomain_elements_begin(sid),
696 mesh.active_local_subdomain_elements_end(sid)),
697 find_bbox);
698
699 // Compare the bounding boxes across processors
700 mesh.comm().min(find_bbox.min());
701 mesh.comm().max(find_bbox.max());
702
703 return find_bbox.bbox();
704}

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

Referenced by 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 723 of file mesh_tools.C.

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

References 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 elements from 2 or more blocks

Definition at line 544 of file mesh_tools.C.

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

References mesh.

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

◆ find_boundary_nodes()

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

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

References mesh.

Referenced by libMesh::VariationalSmootherConstraint::constrain(), libMesh::MeshTools::Modification::distort(), DistortTest::perturb_and_check(), 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 1133 of file mesh_tools.C.

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

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

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

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

References libMesh::DofObject::id().

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

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

References libMesh::DofObject::id().

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

◆ find_nodal_or_face_neighbors()

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

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

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

Definition at line 1092 of file mesh_tools.C.

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

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

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

◆ get_not_subactive_node_ids()

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

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

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

Definition at line 993 of file mesh_tools.C.

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

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

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

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

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

References libMesh::libmesh_assert(), and mesh.

◆ libmesh_assert_consistent_distributed()

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

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

Definition at line 2069 of file mesh_tools.C.

2070{
2071 libmesh_parallel_only(mesh.comm());
2072
2073 dof_id_type parallel_max_elem_id = mesh.max_elem_id();
2074 mesh.comm().max(parallel_max_elem_id);
2075
2076 for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2077 {
2078 const Elem * elem = mesh.query_elem_ptr(i);
2079 processor_id_type pid =
2081 mesh.comm().min(pid);
2082 libmesh_assert(elem || pid != mesh.processor_id());
2083 }
2084
2085 dof_id_type parallel_max_node_id = mesh.max_node_id();
2086 mesh.comm().max(parallel_max_node_id);
2087
2088 for (dof_id_type i=0; i != parallel_max_node_id; ++i)
2089 {
2090 const Node * node = mesh.query_node_ptr(i);
2091 processor_id_type pid =
2093 mesh.comm().min(pid);
2094 libmesh_assert(node || pid != mesh.processor_id());
2095 }
2096}
processor_id_type processor_id() const
Definition dof_object.h:881
virtual const Node * query_node_ptr(const dof_id_type i) const =0
virtual dof_id_type max_elem_id() const =0
virtual const Elem * query_elem_ptr(const dof_id_type i) const =0

References libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::max_node_id(), mesh, libMesh::Parallel::Communicator::min(), libMesh::DofObject::processor_id(), libMesh::ParallelObject::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 2099 of file mesh_tools.C.

2100{
2101 libmesh_parallel_only(mesh.comm());
2102 auto locator = mesh.sub_point_locator();
2103
2104 dof_id_type parallel_max_elem_id = mesh.max_elem_id();
2105 mesh.comm().max(parallel_max_elem_id);
2106
2107 for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2108 {
2109 const Elem * elem = mesh.query_elem_ptr(i);
2110
2111 const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
2112 unsigned int n_nodes = my_n_nodes;
2113 mesh.comm().max(n_nodes);
2114
2115 if (n_nodes)
2116 libmesh_assert(mesh.comm().semiverify(elem ? &my_n_nodes : nullptr));
2117
2118 for (unsigned int n=0; n != n_nodes; ++n)
2119 {
2120 const Node * node = elem ? elem->node_ptr(n) : nullptr;
2121 processor_id_type pid =
2123 mesh.comm().min(pid);
2124 libmesh_assert(node || pid != mesh.processor_id());
2125 }
2126 }
2127}
timpi_pure bool semiverify(const T *r) const
virtual unsigned int n_nodes() const =0
const Node * node_ptr(const unsigned int i) const
Definition elem.h:2516
std::unique_ptr< PointLocatorBase > sub_point_locator() const
Definition mesh_base.C:1833
const dof_id_type n_nodes
Definition tecplot_io.C:67

References libMesh::ParallelObject::comm(), libMesh::DofObject::invalid_processor_id, libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::MeshBase::max_elem_id(), mesh, libMesh::Parallel::Communicator::min(), libMesh::Elem::n_nodes(), n_nodes, libMesh::Elem::node_ptr(), libMesh::DofObject::processor_id(), libMesh::ParallelObject::processor_id(), libMesh::MeshBase::query_elem_ptr(), libMesh::Parallel::Communicator::semiverify(), 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 processor, as is required by libMesh numeric classes.

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

Definition at line 1477 of file mesh_tools.C.

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

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

◆ libmesh_assert_equal_connectivity()

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

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

Definition at line 1701 of file mesh_tools.C.

1702{
1703 LOG_SCOPE("libmesh_assert_equal_connectivity()", "MeshTools");
1704
1705 dof_id_type pmax_elem_id = mesh.max_elem_id();
1706 mesh.comm().max(pmax_elem_id);
1707
1708 for (dof_id_type i=0; i != pmax_elem_id; ++i)
1709 {
1710 const Elem * e = mesh.query_elem_ptr(i);
1711
1712 std::vector<dof_id_type> nodes;
1713 if (e)
1714 for (auto n : e->node_index_range())
1715 nodes.push_back(e->node_id(n));
1716
1717 libmesh_assert(mesh.comm().semiverify(e ? &nodes : nullptr));
1718 }
1719}

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

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

◆ libmesh_assert_equal_n_systems()

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

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

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

Definition at line 1292 of file mesh_tools.C.

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

References libMesh::invalid_uint, and mesh.

◆ libmesh_assert_equal_points()

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

A function for testing that node locations match across processors.

Definition at line 1685 of file mesh_tools.C.

1686{
1687 LOG_SCOPE("libmesh_assert_equal_points()", "MeshTools");
1688
1689 dof_id_type pmax_node_id = mesh.max_node_id();
1690 mesh.comm().max(pmax_node_id);
1691
1692 for (dof_id_type i=0; i != pmax_node_id; ++i)
1693 {
1694 const Point * p = mesh.query_node_ptr(i);
1695
1697 }
1698}

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

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

◆ libmesh_assert_no_links_to_elem()

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

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

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

Definition at line 1666 of file mesh_tools.C.

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

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

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

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

Definition at line 2180 of file mesh_tools.C.

2181{
2182 LOG_SCOPE("libmesh_assert_parallel_consistent_new_node_procids()", "MeshTools");
2183
2184 if (mesh.n_processors() == 1)
2185 return;
2186
2187 libmesh_parallel_only(mesh.comm());
2188
2189 // We want this test to hit every node when called even after nodes
2190 // have been added asynchronously but before everything has been
2191 // renumbered.
2192 dof_id_type parallel_max_elem_id = mesh.max_elem_id();
2193 mesh.comm().max(parallel_max_elem_id);
2194
2195 std::vector<bool> elem_touched_by_anyone(parallel_max_elem_id, false);
2196
2197 for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2198 {
2199 const Elem * elem = mesh.query_elem_ptr(i);
2200
2201 const unsigned int my_n_nodes = elem ? elem->n_nodes() : 0;
2202 unsigned int n_nodes = my_n_nodes;
2203 mesh.comm().max(n_nodes);
2204
2205 if (n_nodes)
2206 libmesh_assert(mesh.comm().semiverify(elem ? &my_n_nodes : nullptr));
2207
2208 for (unsigned int n=0; n != n_nodes; ++n)
2209 {
2210 const Node * node = elem ? elem->node_ptr(n) : nullptr;
2211 const processor_id_type pid = node ? node->processor_id() : 0;
2212 libmesh_assert(mesh.comm().semiverify (node ? &pid : nullptr));
2213 }
2214 }
2215}

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

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

2133{
2134 LOG_SCOPE("libmesh_assert_parallel_consistent_procids()", "MeshTools");
2135
2136 if (mesh.n_processors() == 1)
2137 return;
2138
2139 libmesh_parallel_only(mesh.comm());
2140
2141 // Some code (looking at you, stitch_meshes) modifies DofObject ids
2142 // without keeping max_elem_id()/max_node_id() consistent, but
2143 // that's done in a safe way for performance reasons, so we'll play
2144 // along and just figure out new max ids ourselves.
2145 dof_id_type parallel_max_elem_id = 0;
2146 for (const auto & elem : mesh.element_ptr_range())
2147 parallel_max_elem_id = std::max<dof_id_type>(parallel_max_elem_id,
2148 elem->id()+1);
2149 mesh.comm().max(parallel_max_elem_id);
2150
2151 // Check processor ids for consistency between processors
2152
2153 for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
2154 {
2155 const Elem * elem = mesh.query_elem_ptr(i);
2156
2157 processor_id_type min_id =
2158 elem ? elem->processor_id() :
2159 std::numeric_limits<processor_id_type>::max();
2160 mesh.comm().min(min_id);
2161
2162 processor_id_type max_id =
2163 elem ? elem->processor_id() :
2164 std::numeric_limits<processor_id_type>::min();
2165 mesh.comm().max(max_id);
2166
2167 if (elem)
2168 {
2169 libmesh_assert_equal_to (min_id, elem->processor_id());
2170 libmesh_assert_equal_to (max_id, elem->processor_id());
2171 }
2172
2173 if (min_id == mesh.processor_id())
2174 libmesh_assert(elem);
2175 }
2176}

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

◆ libmesh_assert_parallel_consistent_procids< Node >()

Definition at line 2218 of file mesh_tools.C.

2219{
2220 LOG_SCOPE("libmesh_assert_parallel_consistent_procids()", "MeshTools");
2221
2222 if (mesh.n_processors() == 1)
2223 return;
2224
2225 libmesh_parallel_only(mesh.comm());
2226
2227 // We want this test to be valid even when called even after nodes
2228 // have been added asynchronously but before they're renumbered
2229 //
2230 // Plus, some code (looking at you, stitch_meshes) modifies
2231 // DofObject ids without keeping max_elem_id()/max_node_id()
2232 // consistent, but that's done in a safe way for performance
2233 // reasons, so we'll play along and just figure out new max ids
2234 // ourselves.
2235 dof_id_type parallel_max_node_id = 0;
2236 for (const auto & node : mesh.node_ptr_range())
2237 parallel_max_node_id = std::max<dof_id_type>(parallel_max_node_id,
2238 node->id()+1);
2239 mesh.comm().max(parallel_max_node_id);
2240
2241 std::vector<bool> node_touched_by_anyone(parallel_max_node_id, false);
2242
2243 for (const auto & elem : as_range(mesh.local_elements_begin(),
2244 mesh.local_elements_end()))
2245 {
2246 libmesh_assert (elem);
2247
2248 for (auto & node : elem->node_ref_range())
2249 {
2250 dof_id_type nodeid = node.id();
2251 node_touched_by_anyone[nodeid] = true;
2252 }
2253 }
2254 mesh.comm().max(node_touched_by_anyone);
2255
2256 // Check processor ids for consistency between processors
2257 // on any node an element touches
2258 for (dof_id_type i=0; i != parallel_max_node_id; ++i)
2259 {
2260 if (!node_touched_by_anyone[i])
2261 continue;
2262
2263 const Node * node = mesh.query_node_ptr(i);
2264 const processor_id_type pid = node ? node->processor_id() : 0;
2265
2266 libmesh_assert(mesh.comm().semiverify (node ? &pid : nullptr));
2267 }
2268}
SimpleRange< IndexType > as_range(const std::pair< IndexType, IndexType > &p)
Helper function that allows us to treat a homogenous pair as a range.

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

Referenced by libMesh::UnstructuredMesh::copy_nodes_and_elements(), 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 1519 of file mesh_tools.C.

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

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

◆ libmesh_assert_topology_consistent_procids< Node >()

Definition at line 1563 of file mesh_tools.C.

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

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

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

1422{
1423 LOG_SCOPE("libmesh_assert_valid_amr_elem_ids()", "MeshTools");
1424
1425 for (const auto & elem : mesh.element_ptr_range())
1426 {
1427 libmesh_assert (elem);
1428
1429 const Elem * parent = elem->parent();
1430
1431 if (parent)
1432 {
1433 libmesh_assert_greater_equal (elem->id(), parent->id());
1434 libmesh_assert_greater_equal (elem->processor_id(), parent->processor_id());
1435 }
1436 }
1437}

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

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

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

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

◆ libmesh_assert_valid_boundary_ids()

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

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

Definition at line 1788 of file mesh_tools.C.

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

References libMesh::BoundaryInfo::boundary_ids(), libMesh::ParallelObject::comm(), libMesh::BoundaryInfo::edge_boundary_ids(), libMesh::MeshBase::get_boundary_info(), libMesh::BoundaryInfo::invalid_id, libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::MeshBase::max_elem_id(), mesh, libMesh::Elem::n_edges(), libMesh::Elem::n_nodes(), n_nodes, libMesh::ParallelObject::n_processors(), libMesh::Elem::n_sides(), libMesh::Elem::node_ptr(), libMesh::MeshBase::query_elem_ptr(), libMesh::BoundaryInfo::raw_boundary_ids(), libMesh::BoundaryInfo::raw_edge_boundary_ids(), libMesh::BoundaryInfo::raw_shellface_boundary_ids(), libMesh::Parallel::Communicator::semiverify(), and libMesh::BoundaryInfo::shellface_boundary_ids().

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

◆ libmesh_assert_valid_constraint_rows()

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

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

Definition at line 1745 of file mesh_tools.C.

1746{
1747 libmesh_parallel_only(mesh.comm());
1748
1749 const auto & constraint_rows = mesh.get_constraint_rows();
1750
1751 bool have_constraint_rows = !constraint_rows.empty();
1752 mesh.comm().max(have_constraint_rows);
1753 if (!have_constraint_rows)
1754 return;
1755
1756 for (auto & row : constraint_rows)
1757 {
1758 const Node * node = row.first;
1759 libmesh_assert(node == mesh.node_ptr(node->id()));
1760
1761 for (auto & pr : row.second)
1762 {
1763 const Elem * spline_elem = pr.first.first;
1764 libmesh_assert(spline_elem == mesh.elem_ptr(spline_elem->id()));
1765 }
1766 }
1767
1768 dof_id_type pmax_node_id = mesh.max_node_id();
1769 mesh.comm().max(pmax_node_id);
1770
1771 for (dof_id_type i=0; i != pmax_node_id; ++i)
1772 {
1773 const Node * node = mesh.query_node_ptr(i);
1774
1775 bool have_constraint = constraint_rows.count(node);
1776
1777 const std::size_t my_n_constraints = have_constraint ?
1778 libmesh_map_find(constraint_rows, node).size() : std::size_t(-1);
1779 const std::size_t * n_constraints = node ?
1780 &my_n_constraints : nullptr;
1781
1782 libmesh_assert(mesh.comm().semiverify(n_constraints));
1783 }
1784}
virtual const Node * node_ptr(const dof_id_type i) const =0
virtual const Elem * elem_ptr(const dof_id_type i) const =0

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

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

◆ libmesh_assert_valid_dof_ids()

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

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

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

Definition at line 1958 of file mesh_tools.C.

1959{
1960 LOG_SCOPE("libmesh_assert_valid_dof_ids()", "MeshTools");
1961
1962 if (mesh.n_processors() == 1)
1963 return;
1964
1965 libmesh_parallel_only(mesh.comm());
1966
1967 dof_id_type pmax_elem_id = mesh.max_elem_id();
1968 mesh.comm().max(pmax_elem_id);
1969
1970 for (dof_id_type i=0; i != pmax_elem_id; ++i)
1971 assert_semiverify_dofobj(mesh.comm(),
1973 sysnum);
1974
1975 dof_id_type pmax_node_id = mesh.max_node_id();
1976 mesh.comm().max(pmax_node_id);
1977
1978 for (dof_id_type i=0; i != pmax_node_id; ++i)
1979 assert_semiverify_dofobj(mesh.comm(),
1981 sysnum);
1982}

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

◆ libmesh_assert_valid_elem_ids()

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

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

Definition at line 1398 of file mesh_tools.C.

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

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

2322{
2323 LOG_SCOPE("libmesh_assert_valid_neighbors()", "MeshTools");
2324
2325 for (const auto & elem : mesh.element_ptr_range())
2326 {
2327 libmesh_assert (elem);
2328 elem->libmesh_assert_valid_neighbors();
2329 }
2330
2331 if (mesh.n_processors() == 1)
2332 return;
2333
2334 libmesh_parallel_only(mesh.comm());
2335
2336 dof_id_type pmax_elem_id = mesh.max_elem_id();
2337 mesh.comm().max(pmax_elem_id);
2338
2339 for (dof_id_type i=0; i != pmax_elem_id; ++i)
2340 {
2341 const Elem * elem = mesh.query_elem_ptr(i);
2342
2343 const unsigned int my_n_neigh = elem ? elem->n_neighbors() : 0;
2344 unsigned int n_neigh = my_n_neigh;
2345 mesh.comm().max(n_neigh);
2346 if (elem)
2347 libmesh_assert_equal_to (my_n_neigh, n_neigh);
2348
2349 for (unsigned int n = 0; n != n_neigh; ++n)
2350 {
2351 dof_id_type my_neighbor = DofObject::invalid_id;
2352 dof_id_type * p_my_neighbor = nullptr;
2353
2354 // If we have a non-remote_elem neighbor link, then we can
2355 // verify it.
2356 if (elem && elem->neighbor_ptr(n) != remote_elem)
2357 {
2358 p_my_neighbor = &my_neighbor;
2359 if (elem->neighbor_ptr(n))
2360 my_neighbor = elem->neighbor_ptr(n)->id();
2361
2362 // But wait - if we haven't set remote_elem links yet then
2363 // some nullptr links on ghost elements might be
2364 // future-remote_elem links, so we can't verify those.
2365 if (!assert_valid_remote_elems &&
2366 !elem->neighbor_ptr(n) &&
2367 elem->processor_id() != mesh.processor_id())
2368 p_my_neighbor = nullptr;
2369 }
2370 libmesh_assert(mesh.comm().semiverify(p_my_neighbor));
2371 }
2372 }
2373}
static constexpr dof_id_type invalid_id
An invalid id to distinguish an uninitialized DofObject.
Definition dof_object.h:473

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

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

◆ libmesh_assert_valid_node_pointers()

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

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

Definition at line 1342 of file mesh_tools.C.

1343{
1344 LOG_SCOPE("libmesh_assert_valid_node_pointers()", "MeshTools");
1345
1346 // Here we specifically do not want "auto &" because we need to
1347 // reseat the (temporary) pointer variable in the loop below,
1348 // without modifying the original.
1349 for (const Elem * elem : mesh.element_ptr_range())
1350 {
1351 libmesh_assert (elem);
1352 while (elem)
1353 {
1354 elem->libmesh_assert_valid_node_pointers();
1355 for (auto n : elem->neighbor_ptr_range())
1356 if (n && n != remote_elem)
1358
1359 libmesh_assert_not_equal_to (elem->parent(), remote_elem);
1360 elem = elem->parent();
1361 }
1362 }
1363}
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.

References 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 599 of file mesh_tools.h.

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

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

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

References libMesh::ParallelObject::comm(), libMesh::libmesh_assert(), libMesh::Parallel::Communicator::max(), libMesh::MeshBase::max_elem_id(), mesh, libMesh::Parallel::Communicator::min(), 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 1627 of file mesh_tools.C.

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

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

Referenced by libMesh::DistributedMesh::delete_remote_elements(), and libMesh::MeshCommunication::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 1367 of file mesh_tools.C.

1368{
1369 LOG_SCOPE("libmesh_assert_valid_remote_elems()", "MeshTools");
1370
1371 for (const auto & elem : as_range(mesh.local_elements_begin(),
1372 mesh.local_elements_end()))
1373 {
1374 libmesh_assert (elem);
1375
1376 // We currently don't allow active_local_elements to have
1377 // remote_elem neighbors
1378 if (elem->active())
1379 for (auto n : elem->neighbor_ptr_range())
1380 libmesh_assert_not_equal_to (n, remote_elem);
1381
1382#ifdef LIBMESH_ENABLE_AMR
1383 const Elem * parent = elem->parent();
1384 if (parent)
1385 libmesh_assert_not_equal_to (parent, remote_elem);
1386
1387 // We can only be strict about active elements' subactive
1388 // children
1389 if (elem->active() && elem->has_children())
1390 for (auto & child : elem->child_ref_range())
1391 libmesh_assert_not_equal_to (&child, remote_elem);
1392#endif
1393 }
1394}

References libMesh::as_range(), libMesh::libmesh_assert(), 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.

Definition at line 1986 of file mesh_tools.C.

1987{
1988 LOG_SCOPE("libmesh_assert_valid_unique_ids()", "MeshTools");
1989
1990 libmesh_parallel_only(mesh.comm());
1991
1992 // Storage for semi-local DofObject ids.
1993 std::unordered_set<unique_id_type> semilocal_unique_ids;
1994
1995 auto gather_elem_ids = [&]()
1996 {
1997 for (auto const & elem : mesh.active_element_ptr_range())
1998 {
1999 auto [it, inserted] = semilocal_unique_ids.insert(elem->unique_id());
2000 libmesh_assert(inserted);
2001 libmesh_ignore(it);
2002 }
2003 };
2004
2005 auto gather_node_ids = [&]()
2006 {
2007 for (auto const & node : mesh.node_ptr_range())
2008 {
2009 auto [it, inserted] = semilocal_unique_ids.insert(node->unique_id());
2010 libmesh_assert(inserted);
2011 libmesh_ignore(it);
2012 }
2013 };
2014
2015 auto verify_elems = [&]()
2016 {
2017 dof_id_type pmax_elem_id = mesh.max_elem_id();
2018 mesh.comm().max(pmax_elem_id);
2019
2020 for (auto i : make_range(pmax_elem_id))
2021 {
2022 const Elem * elem = mesh.query_elem_ptr(i);
2023 assert_dofobj_unique_id(mesh.comm(), elem, semilocal_unique_ids);
2024 }
2025 };
2026
2027 auto verify_nodes = [&]()
2028 {
2029 dof_id_type pmax_node_id = mesh.max_node_id();
2030 mesh.comm().max(pmax_node_id);
2031
2032 for (auto i : make_range(pmax_node_id))
2033 {
2034 const Node * node = mesh.query_node_ptr(i);
2035 assert_dofobj_unique_id(mesh.comm(), node, semilocal_unique_ids);
2036 }
2037 };
2038
2040 {
2041 // First collect all the unique_ids we can see and make sure there's
2042 // no duplicates
2043 gather_elem_ids();
2044 gather_node_ids();
2045
2046 // Then make sure elements/nodes are all in sync and remote
2047 // elements don't duplicate semilocal
2048 verify_elems();
2049 verify_nodes();
2050 }
2051 else
2052 {
2053 // If the mesh allows Node and Elem unique_ids to overlap, then we only
2054 // check for validity and uniqueness of an Elem (resp. Node) unique id
2055 // within the set of Elem (resp. Node) unique_ids.
2056 gather_elem_ids();
2057 verify_elems();
2058
2059 // Clear id list before checking Nodes
2060 semilocal_unique_ids.clear();
2061
2062 // Finally, check Nodes
2063 gather_node_ids();
2064 verify_nodes();
2065 }
2066}
void allow_node_and_elem_unique_id_overlap(bool allow)
If true is passed, then this mesh will no longer require unique_ids to be unique across the set of al...
Definition mesh_base.h:1387

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

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

◆ n_active_elem_of_type()

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

Implemented in terms of active_type_element_iterators.

Definition at line 744 of file mesh_tools.C.

746{
747 return static_cast<dof_id_type>(std::distance(mesh.active_type_elements_begin(type),
748 mesh.active_type_elements_end (type)));
749}

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

797{
798 libmesh_parallel_only(mesh.comm());
799
800 unsigned int nl = n_active_local_levels(mesh);
801
802 for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
803 mesh.unpartitioned_elements_end()))
804 if (elem->active())
805 nl = std::max(elem->level() + 1, nl);
806
807 mesh.comm().max(nl);
808 return nl;
809}
unsigned int n_active_local_levels(const MeshBase &mesh)
Definition mesh_tools.C:767

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

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

768{
769 struct LevelCounter {
770 unsigned int nl;
771
772 LevelCounter () : nl(0) {}
773
774 LevelCounter (LevelCounter &, Threads::split) :
775 nl(0) {}
776
777 void operator()(const ConstElemRange & range) {
778 for (const Elem * elem : range)
779 nl = std::max(elem->level() + 1, nl);
780 }
781
782 void join(const LevelCounter & other) {
783 nl = std::max(nl, other.nl);
784 }
785 };
786
787 LevelCounter counter;
788
790
791 return counter.nl;
792}
const ConstElemRange & active_local_element_stored_range() const
Definition mesh_base.C:1954
Dummy "splitting object" used to distinguish splitting constructors from copy constructors.

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

Referenced by n_active_levels().

◆ n_connected_components()

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

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

Definition at line 864 of file mesh_tools.C.

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

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

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

◆ n_elem()

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

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

Definition at line 1004 of file mesh_tools.C.

1006{
1007 return cast_int<dof_id_type>(std::distance(begin, end));
1008}

Referenced by libMesh::MeshTools::Subdivision::add_boundary_ghosts(), correct_node_proc_ids(), libMesh::Partitioner::partition_unpartitioned_elements(), libMesh::Partitioner::set_node_processor_ids(), libMesh::Partitioner::set_parent_processor_ids(), and libMesh::XdrIO::write_serialized_connectivity().

◆ n_elem_of_type()

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

Implemented in terms of type_element_iterators.

Definition at line 735 of file mesh_tools.C.

737{
738 return static_cast<dof_id_type>(std::distance(mesh.type_elements_begin(type),
739 mesh.type_elements_end (type)));
740}

References mesh.

◆ n_levels()

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

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

Definition at line 826 of file mesh_tools.C.

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

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

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

◆ n_local_levels()

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

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

Definition at line 813 of file mesh_tools.C.

814{
815 unsigned int nl = 0;
816
817 for (const auto & elem : as_range(mesh.local_elements_begin(),
818 mesh.local_elements_end()))
819 nl = std::max(elem->level() + 1, nl);
820
821 return nl;
822}

References libMesh::as_range(), 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 1012 of file mesh_tools.C.

1014{
1015 return cast_int<dof_id_type>(std::distance(begin, end));
1016}

◆ n_non_subactive_elem_of_type_at_level()

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

Definition at line 751 of file mesh_tools.C.

754{
755 dof_id_type cnt = 0;
756
757 // iterate over the elements of the specified type
758 for (const auto & elem : as_range(mesh.type_elements_begin(type),
759 mesh.type_elements_end(type)))
760 if ((elem->level() == level) && !elem->subactive())
761 cnt++;
762
763 return cnt;
764}

References libMesh::as_range(), and mesh.

◆ n_p_levels()

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

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

Definition at line 1049 of file mesh_tools.C.

1050{
1051 libmesh_parallel_only(mesh.comm());
1052
1053 unsigned int max_p_level = 0;
1054
1055 // first my local elements
1056 for (const auto & elem : as_range(mesh.local_elements_begin(),
1057 mesh.local_elements_end()))
1058 max_p_level = std::max(elem->p_level(), max_p_level);
1059
1060 // then any unpartitioned objects
1061 for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
1062 mesh.unpartitioned_elements_end()))
1063 max_p_level = std::max(elem->p_level(), max_p_level);
1064
1065 mesh.comm().max(max_p_level);
1066 return max_p_level + 1;
1067}

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

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

851{
852 libmesh_parallel_only(mesh.comm());
853
854 unsigned int nl = 0;
855 for (const auto & elem : mesh.element_ptr_range())
856 nl = std::max(elem->level() + 1, nl);
857
858 mesh.comm().max(nl);
859 return nl;
860}

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

Referenced by n_levels().

◆ processor_bounding_sphere()

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

Definition at line 670 of file mesh_tools.C.

672{
675
676 const Real diag = (bbox.second - bbox.first).norm();
677 const Point cent = (bbox.second + bbox.first)/2;
678
679 return Sphere (cent, .5*diag);
680}
libMesh::BoundingBox create_processor_bounding_box(const MeshBase &mesh, const processor_id_type pid)
Definition mesh_tools.C:645

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

◆ subdomain_bounding_sphere()

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

Definition at line 709 of file mesh_tools.C.

711{
714
715 const Real diag = (bbox.second - bbox.first).norm();
716 const Point cent = (bbox.second + bbox.first)/2;
717
718 return Sphere (cent, .5*diag);
719}
libMesh::BoundingBox create_subdomain_bounding_box(const MeshBase &mesh, const subdomain_id_type sid)
Definition mesh_tools.C:685

References create_subdomain_bounding_box(), mesh, 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 421 of file mesh_tools.C.

422{
423 if (!mesh.is_serial())
424 {
425 libmesh_parallel_only(mesh.comm());
427 mesh.comm().sum(weight);
428 dof_id_type unpartitioned_weight =
430 return weight + unpartitioned_weight;
431 }
432
433 SumElemWeight sew;
434
436 mesh.elements_end()),
437 sew);
438 return sew.weight();
439
440}
dof_id_type weight(const MeshBase &mesh, const processor_id_type pid)
Definition mesh_tools.C:444

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

◆ valid_is_prepared()

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

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

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

Definition at line 1256 of file mesh_tools.C.

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

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

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

◆ volume()

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

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

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

Definition at line 1020 of file mesh_tools.C.

1022{
1023 libmesh_parallel_only(mesh.comm());
1024
1027
1028 Real vol = 0;
1029
1030 // first my local elements
1031 for (const auto & elem : as_range(mesh.local_elements_begin(),
1032 mesh.local_elements_end()))
1033 if (elem->dim() == dim)
1034 vol += elem->volume();
1035
1036 // then count any unpartitioned objects, once
1037 if (mesh.processor_id() == 0)
1038 for (const auto & elem : as_range(mesh.unpartitioned_elements_begin(),
1039 mesh.unpartitioned_elements_end()))
1040 if (elem->dim() == dim)
1041 vol += elem->volume();
1042
1043 mesh.comm().sum(vol);
1044 return vol;
1045}
unsigned int dim
unsigned int mesh_dimension() const
Definition mesh_base.C:430
Real volume(const MeshBase &mesh, unsigned int dim=libMesh::invalid_uint)
Find the total volume of a mesh (interpreting that as area for dim = 2, or total arc length for dim =...

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

Referenced by AllRBBTest::test_box(), AllRBBTest::test_circle(), AllRBBTest::test_cylinder(), AllRBBTest::test_disk(), AllTriTest::test_helper(), AllTriTest::test_helper_c0polyhedron(), AllRBBTest::test_sphere(), AllTriTest::testAllTriC0PolygonOctagon(), MeshGenerationTest::testBuildCube(), MeshTetTest::testHole(), MeshTetTest::testNetGenQuadratic(), MeshTetTest::testNetGenTet14(), MeshTetTest::testTetInterfaceBase(), and MeshTetTest::testTetsToTets().

◆ weight() [1/2]

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

Definition at line 78 of file mesh_tools.h.

79{ 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 
)
Returns
The sum over all the elements on processor pid of nodes per element.

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

Definition at line 444 of file mesh_tools.C.

445{
446 SumElemWeight sew;
447
448 Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
449 mesh.pid_elements_end(pid)),
450 sew);
451 return sew.weight();
452}

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

Referenced by libMesh::MeshTools::Modification::smooth(), total_weight(), and weight().