Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner 3 : 4 : // This library is free software; you can redistribute it and/or 5 : // modify it under the terms of the GNU Lesser General Public 6 : // License as published by the Free Software Foundation; either 7 : // version 2.1 of the License, or (at your option) any later version. 8 : 9 : // This library is distributed in the hope that it will be useful, 10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 : // Lesser General Public License for more details. 13 : 14 : // You should have received a copy of the GNU Lesser General Public 15 : // License along with this library; if not, write to the Free Software 16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 : 18 : 19 : 20 : // Local Includes 21 : #include "libmesh/point_locator_base.h" 22 : #include "libmesh/point_locator_tree.h" 23 : #include "libmesh/elem.h" 24 : #include "libmesh/enum_point_locator_type.h" 25 : #include "libmesh/mesh_base.h" 26 : #include "libmesh/point_locator_nanoflann.h" 27 : 28 : namespace libMesh 29 : { 30 : 31 : 32 : 33 : 34 : //------------------------------------------------------------------ 35 : // PointLocatorBase methods 36 500079 : PointLocatorBase::PointLocatorBase (const MeshBase & mesh, 37 500079 : const PointLocatorBase * master) : 38 387481 : _verbose (false), 39 387481 : _master (master), 40 387481 : _mesh (mesh), 41 387481 : _initialized (false), 42 387481 : _use_close_to_point_tol (false), 43 387481 : _close_to_point_tol (TOLERANCE), 44 387481 : _use_contains_point_tol (false), 45 500079 : _contains_point_tol (TOLERANCE) 46 : { 47 : // If we have a non-nullptr master, inherit its close-to-point tolerances. 48 500079 : if (_master) 49 : { 50 487532 : _use_close_to_point_tol = _master->_use_close_to_point_tol; 51 487532 : _close_to_point_tol = _master->_close_to_point_tol; 52 : } 53 500079 : } 54 : 55 : 56 : 57 387481 : PointLocatorBase::~PointLocatorBase () = default; 58 : 59 : 60 : 61 488059 : bool PointLocatorBase::initialized () const 62 : { 63 488059 : return this->_initialized; 64 : } 65 : 66 : 67 : 68 500073 : std::unique_ptr<PointLocatorBase> PointLocatorBase::build (PointLocatorType t, 69 : const MeshBase & mesh, 70 : const PointLocatorBase * master) 71 : { 72 500073 : switch (t) 73 : { 74 0 : case TREE: 75 0 : return std::make_unique<PointLocatorTree>(mesh, /*Trees::NODES,*/ master); 76 : 77 500073 : case TREE_ELEMENTS: 78 500073 : return std::make_unique<PointLocatorTree>(mesh, Trees::ELEMENTS, master); 79 : 80 0 : case TREE_LOCAL_ELEMENTS: 81 0 : return std::make_unique<PointLocatorTree>(mesh, Trees::LOCAL_ELEMENTS, master); 82 : 83 : #ifdef LIBMESH_HAVE_NANOFLANN 84 0 : case NANOFLANN: 85 0 : return std::make_unique<PointLocatorNanoflann>(mesh, master); 86 : #endif 87 : 88 0 : default: 89 0 : libmesh_error_msg("ERROR: Bad PointLocatorType = " << t); 90 : } 91 : } 92 : 93 527 : Real PointLocatorBase::get_close_to_point_tol () const 94 : { 95 527 : return _close_to_point_tol; 96 : } 97 : 98 : 99 598 : void PointLocatorBase::set_close_to_point_tol (Real close_to_point_tol) 100 : { 101 598 : _use_close_to_point_tol = true; 102 598 : _close_to_point_tol = close_to_point_tol; 103 598 : } 104 : 105 0 : void PointLocatorBase::unset_close_to_point_tol () 106 : { 107 0 : _use_close_to_point_tol = false; 108 0 : _close_to_point_tol = TOLERANCE; 109 0 : } 110 : 111 598 : void PointLocatorBase::set_contains_point_tol(Real contains_point_tol) 112 : { 113 598 : _use_contains_point_tol = true; 114 598 : _contains_point_tol = contains_point_tol; 115 598 : } 116 : 117 0 : void PointLocatorBase::unset_contains_point_tol() 118 : { 119 0 : _use_contains_point_tol = false; 120 0 : _contains_point_tol = TOLERANCE; 121 0 : } 122 : 123 0 : Real PointLocatorBase::get_contains_point_tol() const 124 : { 125 0 : return _contains_point_tol; 126 : } 127 : 128 61148 : const MeshBase & PointLocatorBase::get_mesh () const 129 : { 130 61148 : return _mesh; 131 : } 132 : 133 : 134 : const Node * 135 20874 : PointLocatorBase:: 136 : locate_node(const Point & p, 137 : const std::set<subdomain_id_type> * allowed_subdomains, 138 : Real tol) const 139 : { 140 1176 : std::set<const Elem *> candidate_elements; 141 20874 : this->operator()(p, candidate_elements, allowed_subdomains); 142 : 143 20874 : for (const auto & elem : candidate_elements) 144 : { 145 10919 : const int elem_n_nodes = elem->n_nodes(); 146 10919 : const Real hmax = elem->hmax(); 147 10919 : const Real dist_tol_sq = (tol * hmax) * (tol * hmax); 148 : 149 44308 : for (int n=0; n != elem_n_nodes; ++n) 150 46545 : if ((elem->point(n) - p).norm_sq() < dist_tol_sq) 151 588 : return elem->node_ptr(n); 152 : } 153 : 154 0 : return nullptr; 155 : } 156 : 157 : 158 : #ifndef NDEBUG 159 0 : void PointLocatorBase::libmesh_assert_valid_point_locator () 160 : { 161 : // We might only have been built with TREE_LOCAL_ELEMENTS as an 162 : // option; let's just check local elements to be safe. 163 0 : for (const Elem * elem : this->_mesh.active_local_element_ptr_range()) 164 : { 165 : // For non-Lagrange mappings, we might have nodes that are 166 : // really control points, not contained in the element they 167 : // define; we can only safely check containment of vertices. 168 0 : auto range = make_range(0u, (elem->mapping_type() == LAGRANGE_MAP) ? 169 0 : elem->n_nodes() : elem->n_vertices()); 170 : 171 0 : for (auto n : range) 172 : { 173 0 : const Node & node = elem->node_ref(n); 174 0 : std::set<const Elem *> candidate_elements; 175 0 : this->operator()(node, candidate_elements); 176 0 : libmesh_assert(candidate_elements.count(elem)); 177 : } 178 : } 179 0 : } 180 : #endif 181 : 182 : } // namespace libMesh