diff --git a/include/utils/point_locator_base.h b/include/utils/point_locator_base.h index 400d003096..92ade949d2 100644 --- a/include/utils/point_locator_base.h +++ b/include/utils/point_locator_base.h @@ -196,6 +196,35 @@ class PointLocatorBase : public ReferenceCountedObject */ const MeshBase & get_mesh() const; + /** + * Get the verbosity setting (whether to print extra info to screen, + * default false) for this PointLocator + */ + bool get_verbose() const { return _verbose; } + + /** + * Set the verbosity setting for this PointLocator + */ + void set_verbose(bool verbosity) { _verbose = verbosity; } + +#ifndef NDEBUG + /** + * Verifies that, for every node of every element, the point locator + * finds that element when searching at that node. This is an + * O(N log N) operation, and so only available in builds with NDEBUG + * undefined, for asserting internal consistency (the PointLocator + * works) and external consistency (user code didn't change the mesh + * without updating the PointLocator afterward) that we hope should + * never be broken in opt. + */ + void libmesh_assert_valid_point_locator (); +#endif + + +#ifndef LIBMESH_ENABLE_DEPRECATED +protected: +#endif + /** * Boolean flag to indicate whether to print out extra info. */ diff --git a/src/utils/point_locator_base.C b/src/utils/point_locator_base.C index eb93f3248b..76d1e3c710 100644 --- a/src/utils/point_locator_base.C +++ b/src/utils/point_locator_base.C @@ -22,6 +22,7 @@ #include "libmesh/point_locator_tree.h" #include "libmesh/elem.h" #include "libmesh/enum_point_locator_type.h" +#include "libmesh/mesh_base.h" #include "libmesh/point_locator_nanoflann.h" namespace libMesh @@ -153,4 +154,29 @@ locate_node(const Point & p, return nullptr; } + +#ifndef NDEBUG +void PointLocatorBase::libmesh_assert_valid_point_locator () +{ + // We might only have been built with TREE_LOCAL_ELEMENTS as an + // option; let's just check local elements to be safe. + for (const Elem * elem : this->_mesh.active_local_element_ptr_range()) + { + // For non-Lagrange mappings, we might have nodes that are + // really control points, not contained in the element they + // define; we can only safely check containment of vertices. + auto range = make_range(0u, (elem->mapping_type() == LAGRANGE_MAP) ? + elem->n_nodes() : elem->n_vertices()); + + for (auto n : range) + { + const Node & node = elem->node_ref(n); + std::set candidate_elements; + this->operator()(node, candidate_elements); + libmesh_assert(candidate_elements.count(elem)); + } + } +} +#endif + } // namespace libMesh diff --git a/src/utils/point_locator_tree.C b/src/utils/point_locator_tree.C index 2cc35c165c..4f171a4b8c 100644 --- a/src/utils/point_locator_tree.C +++ b/src/utils/point_locator_tree.C @@ -175,6 +175,10 @@ void PointLocatorTree::init (Trees::BuildType build_type) // ready for take-off this->_initialized = true; + + // This may be too expensive to use even in debug mode, but it's + // helpful to uncomment for debugging. + // this->libmesh_assert_valid_point_locator(); } const Elem * PointLocatorTree::operator() (const Point & p,