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 : // Local Includes 19 : #include "libmesh/libmesh_config.h" 20 : 21 : #ifdef LIBMESH_ENABLE_PERIODIC 22 : 23 : #include "libmesh/periodic_boundaries.h" 24 : #include "libmesh/boundary_info.h" 25 : #include "libmesh/elem.h" 26 : #include "libmesh/mesh_base.h" 27 : #include "libmesh/periodic_boundary.h" 28 : #include "libmesh/point_locator_base.h" 29 : #include "libmesh/remote_elem.h" 30 : 31 : namespace libMesh 32 : { 33 : 34 223807 : PeriodicBoundaries::~PeriodicBoundaries() = default; 35 : 36 : 37 : 38 513 : PeriodicBoundaryBase * PeriodicBoundaries::boundary(boundary_id_type id) 39 : { 40 22 : iterator i = this->find(id); 41 513 : if (i == this->end()) 42 22 : return nullptr; 43 0 : return i->second.get(); 44 : } 45 : 46 : 47 : 48 275482 : const PeriodicBoundaryBase * PeriodicBoundaries::boundary(boundary_id_type id) const 49 : { 50 72570 : const_iterator i = this->find(id); 51 275482 : if (i == this->end()) 52 812 : return nullptr; 53 266452 : return i->second.get(); 54 : } 55 : 56 : 57 : 58 : 59 61148 : const Elem * PeriodicBoundaries::neighbor(boundary_id_type boundary_id, 60 : const PointLocatorBase & point_locator, 61 : const Elem * e, 62 : unsigned int side, 63 : unsigned int * neigh_side) const 64 : { 65 61148 : std::unique_ptr<const Elem> neigh_side_proxy; 66 : 67 : // Find a point on that side (and only that side) 68 61148 : Point p = e->build_side_ptr(side)->vertex_average(); 69 : 70 61148 : const PeriodicBoundaryBase * b = this->boundary(boundary_id); 71 25364 : libmesh_assert (b); 72 61148 : p = b->get_corresponding_pos(p); 73 : 74 50728 : std::set<const Elem *> candidate_elements; 75 61148 : point_locator.operator()(p, candidate_elements); 76 : 77 : // We might have found multiple elements, e.g. if two distinct periodic 78 : // boundaries are overlapping (see systems_of_equations_ex9, for example). 79 : // As a result, we need to search for the element that has boundary_id. 80 61148 : const MeshBase & mesh = point_locator.get_mesh(); 81 63061 : for(const Elem * elem_it : candidate_elements) 82 : { 83 : std::vector<unsigned int> neigh_sides = 84 63061 : mesh.get_boundary_info().sides_with_boundary_id(elem_it, b->pairedboundary); 85 : 86 63187 : for (auto ns : neigh_sides) 87 : { 88 61274 : if (neigh_side) 89 : { 90 20190 : elem_it->build_side_ptr(neigh_side_proxy, ns); 91 20190 : if (neigh_side_proxy->contains_point(p)) 92 : { 93 20064 : *neigh_side = ns; 94 39740 : return elem_it; 95 : } 96 : } 97 : else 98 : // checking contains_point is too expensive if we don't 99 : // definitely need it to find neigh_side 100 41084 : return elem_it; 101 : } 102 : } 103 : 104 : // If we should have found a periodic neighbor but didn't then 105 : // either we're on a ghosted element with a remote periodic neighbor 106 : // or we're on a mesh with an inconsistent periodic boundary. 107 0 : libmesh_error_msg_if(mesh.is_serial() || 108 : (e->processor_id() == mesh.processor_id()), 109 : "Periodic boundary neighbor not found"); 110 : 111 0 : if (neigh_side) 112 0 : *neigh_side = libMesh::invalid_uint; 113 0 : return remote_elem; 114 16848 : } 115 : 116 : } // namespace libMesh 117 : 118 : 119 : 120 : 121 : 122 : #endif // LIBMESH_ENABLE_PERIODIC