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_neighbor_coupling.h" 22 : 23 : #include "libmesh/elem.h" 24 : #include "libmesh/periodic_boundaries.h" 25 : #include "libmesh/remote_elem.h" 26 : #include "libmesh/libmesh_logging.h" 27 : 28 : // C++ Includes 29 : #include <unordered_set> 30 : 31 : namespace libMesh 32 : { 33 : 34 970 : void PointNeighborCoupling::mesh_reinit() 35 : { 36 : // Unless we have periodic boundary conditions, we don't need 37 : // anything precomputed. 38 : #ifdef LIBMESH_ENABLE_PERIODIC 39 970 : if (_periodic_bcs && !_periodic_bcs->empty()) 40 : #endif 41 : { 42 : // If we do have periodic boundary conditions, we'll need a master 43 : // point locator, so we'd better have a mesh to build it on. 44 0 : libmesh_assert(_mesh); 45 : 46 : // Make sure an up-to-date master point locator has been 47 : // constructed; we'll need to grab sub-locators soon. 48 0 : _mesh->sub_point_locator(); 49 : } 50 970 : } 51 : 52 : 53 : 54 788 : void PointNeighborCoupling::operator() 55 : (const MeshBase::const_element_iterator & range_begin, 56 : const MeshBase::const_element_iterator & range_end, 57 : processor_id_type p, 58 : map_type & coupled_elements) 59 : { 60 8 : LOG_SCOPE("operator()", "PointNeighborCoupling"); 61 : 62 : // Take out of libmesh_assert for an API integration 63 : //libmesh_assert(_mesh); 64 : 65 : #ifdef LIBMESH_ENABLE_PERIODIC 66 : bool check_periodic_bcs = 67 788 : (_periodic_bcs && !_periodic_bcs->empty()); 68 772 : std::unique_ptr<PointLocatorBase> point_locator; 69 8 : if (check_periodic_bcs) 70 : { 71 0 : libmesh_assert(_mesh); 72 0 : point_locator = _mesh->sub_point_locator(); 73 : } 74 : #endif 75 : 76 788 : if (!this->_n_levels) 77 : { 78 0 : for (const auto & elem : as_range(range_begin, range_end)) 79 : { 80 : //libmesh_assert(_mesh->query_elem_ptr(elem->id()) == elem); 81 0 : if (elem->processor_id() != p) 82 0 : coupled_elements.emplace(elem, _dof_coupling); 83 0 : } 84 : 85 0 : return; 86 : } 87 : 88 : typedef std::unordered_set<const Elem*> set_type; 89 1584 : set_type next_elements_to_check(range_begin, range_end); 90 16 : set_type elements_to_check; 91 16 : set_type elements_checked; 92 : 93 3152 : for (unsigned int i=0; i != this->_n_levels; ++i) 94 : { 95 24 : elements_to_check.swap(next_elements_to_check); 96 24 : next_elements_to_check.clear(); 97 2340 : elements_checked.insert(elements_to_check.begin(), elements_to_check.end()); 98 : 99 22148 : for (const auto & elem : elements_to_check) 100 : { 101 794 : std::set<const Elem *> point_neighbors; 102 : //libmesh_assert(_mesh->query_elem_ptr(elem->id()) == elem); 103 : 104 19784 : if (elem->processor_id() != p) 105 16094 : coupled_elements.emplace(elem, _dof_coupling); 106 : 107 : #ifdef LIBMESH_ENABLE_PERIODIC 108 : // We might have a periodic neighbor here 109 19784 : if (check_periodic_bcs) 110 : { 111 0 : libmesh_not_implemented(); 112 : } 113 : else 114 : #endif 115 : { 116 19784 : elem->find_point_neighbors(point_neighbors); 117 : } 118 : 119 322351 : for (const auto & neighbor : point_neighbors) 120 : { 121 11340 : if (!elements_checked.count(neighbor)) 122 971 : next_elements_to_check.insert(neighbor); 123 : 124 302567 : if (neighbor->processor_id() != p) 125 250745 : coupled_elements.emplace(neighbor, _dof_coupling); 126 : } 127 : } 128 : } 129 772 : } 130 : 131 : 132 : } // namespace libMesh