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/overlap_coupling.h" 22 : 23 : #include "libmesh/elem.h" 24 : #include "libmesh/enum_quadrature_type.h" 25 : #include "libmesh/periodic_boundaries.h" 26 : #include "libmesh/remote_elem.h" 27 : #include "libmesh/libmesh_logging.h" 28 : 29 : // C++ Includes 30 : #include <unordered_set> 31 : 32 : namespace libMesh 33 : { 34 : 35 213 : OverlapCoupling::OverlapCoupling() : 36 213 : _dof_coupling(nullptr) 37 : { 38 414 : _q_rules[0] = QBase::build(QSIMPSON, 1, SECOND); 39 414 : _q_rules[1] = QBase::build(QSIMPSON, 2, SECOND); 40 414 : _q_rules[2] = QBase::build(QSIMPSON, 3, SECOND); 41 213 : } 42 : 43 : 44 : 45 0 : OverlapCoupling::OverlapCoupling(const OverlapCoupling & other) : 46 : GhostingFunctor(other), 47 0 : _dof_coupling(other._dof_coupling) 48 : { 49 0 : for (auto i : make_range(2)) 50 0 : if (other._q_rules[i].get()) 51 0 : _q_rules[i] = other._q_rules[i]->clone(); 52 0 : } 53 : 54 : 55 : 56 0 : void OverlapCoupling::set_quadrature_rule 57 : (std::unique_ptr<QBase> new_q_rule) 58 : { 59 0 : libmesh_assert(new_q_rule.get()); 60 0 : const unsigned int dim = new_q_rule->get_dim(); 61 0 : _q_rules[dim-1] = std::move(new_q_rule); 62 0 : } 63 : 64 : 65 : 66 2220 : void OverlapCoupling::mesh_reinit() 67 : { 68 : // We'll need a master point locator, so we'd better have a mesh 69 : // to build it on. 70 36 : libmesh_assert(_mesh); 71 : 72 : // Make sure an up-to-date master point locator has been 73 : // constructed; we'll need to grab sub-locators soon. 74 2220 : _mesh->sub_point_locator(); 75 2220 : } 76 : 77 : 78 : 79 3654 : void OverlapCoupling::operator() 80 : (const MeshBase::const_element_iterator & range_begin, 81 : const MeshBase::const_element_iterator & range_end, 82 : processor_id_type p, 83 : map_type & coupled_elements) 84 : { 85 36 : LOG_SCOPE("operator()", "OverlapCoupling"); 86 : 87 : std::unique_ptr<PointLocatorBase> point_locator 88 3672 : = _mesh->sub_point_locator(); 89 : 90 3654 : const std::vector<Point> & xyz = this->_fe_map.get_xyz(); 91 : 92 39366 : for (const auto & elem : as_range(range_begin, range_end)) 93 : { 94 16542 : const unsigned int dim = elem->dim(); 95 : 96 16542 : QBase & qrule = *_q_rules[dim-1]; 97 16542 : qrule.init(*elem); 98 : 99 17046 : _fe_map.init_reference_to_physical_map(dim, qrule.get_points(), elem); 100 17046 : _fe_map.compute_map(dim, qrule.get_weights(), elem, /*d2phi=*/ false); 101 : 102 1008 : std::set<const Elem *> overlapping_elements; 103 165420 : for (const Point & qp : xyz) 104 148878 : (*point_locator)(qp, overlapping_elements); 105 : 106 : // We should at least find ourselves 107 504 : libmesh_assert(overlapping_elements.count(elem)); 108 : 109 134904 : for (const Elem * e : overlapping_elements) 110 118362 : if (e->processor_id() != p) 111 37170 : coupled_elements.emplace(e, _dof_coupling); 112 3618 : } 113 3654 : } 114 : 115 : 116 : } // namespace libMesh