LCOV - code coverage report
Current view: top level - src/mesh - sides_to_elem_map.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 29 31 93.5 %
Date: 2025-08-19 19:27:09 Functions: 6 6 100.0 %
Legend: Lines: hit not hit

          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             : // libMesh includes
      19             : #include "libmesh/sides_to_elem_map.h"
      20             : #include "libmesh/elem.h"
      21             : #include "libmesh/libmesh_logging.h" // LOG_SCOPE
      22             : #include "libmesh/mesh_base.h"
      23             : #include "libmesh/utility.h" // libmesh_map_find()
      24             : 
      25             : namespace libMesh
      26             : {
      27             : 
      28             : namespace MeshTools
      29             : {
      30             : 
      31         796 : SidesToElemMap::SidesToElemMap() = default;
      32         796 : SidesToElemMap::~SidesToElemMap() = default;
      33             : 
      34             : /**
      35             :  * Static build function
      36             :  */
      37         844 : SidesToElemMap SidesToElemMap::build(const MeshBase & mesh)
      38             : {
      39          48 :   LOG_SCOPE("build()", "SidesToElemMap");
      40             : 
      41             :   // Eventual return value
      42         844 :   SidesToElemMap ret;
      43             : 
      44             :   // Temporary storage of sorted list of vertex ids on side "s" of
      45             :   // "elem".  We use only vertices since that is sufficient to
      46             :   // uniquely identify an Elem side. We only create this once and then
      47             :   // reuse it for each Side in the mesh to avoid repeated small memory
      48             :   // allocations.
      49          48 :   std::vector<dof_id_type> sorted_vertex_ids;
      50             : 
      51             :   // Flag which is used to check for hanging Nodes, a case not
      52             :   // currently handled by the SidesToElemMap object.
      53          24 :   unsigned int active_level_seen = libMesh::invalid_uint;
      54             : 
      55       31184 :   for (const auto & elem : mesh.element_ptr_range())
      56             :   {
      57             :     // We currently don't handle meshes with hanging nodes. That is,
      58             :     // if there is a refined element with a coarser neighbor, the
      59             :     // SidesToElemMap won't contain any neighbor information (in
      60             :     // either direction) about this. For now, we throw an error
      61             :     // in this scenario.
      62       15192 :     if (elem->active())
      63             :       {
      64       15192 :         if (active_level_seen == libMesh::invalid_uint)
      65         844 :           active_level_seen = elem->level();
      66             :         else
      67       14348 :           libmesh_error_msg_if(
      68             :             active_level_seen != elem->level(),
      69             :             "SidesToElemMap does not currently support hanging nodes.");
      70             :       }
      71             : 
      72       76392 :     for (auto s : elem->side_index_range())
      73             :     {
      74       60768 :       ret.get_sorted_vertex_ids(elem, s, sorted_vertex_ids);
      75             : 
      76             :       // Get reference to (or create) the vector of Elem pointers
      77             :       // associated with this list of vertex ids, and store "elem" in it.
      78       60768 :       ret._sides_to_elem_map[sorted_vertex_ids].push_back(elem);
      79             :     }
      80         796 :   }
      81             : 
      82         868 :   return ret;
      83           0 : }
      84             : 
      85             : std::pair<SidesToElemMap::ElemIter, SidesToElemMap::ElemIter>
      86        8016 : SidesToElemMap::get_connected_elems(const Elem * elem, unsigned int side) const
      87             : {
      88         624 :   std::vector<dof_id_type> sorted_vertex_ids;
      89        8016 :   this->get_sorted_vertex_ids(elem, side, sorted_vertex_ids);
      90             : 
      91        8016 :   const auto & elem_vec = libmesh_map_find(_sides_to_elem_map, sorted_vertex_ids);
      92        9264 :   return std::make_pair(elem_vec.begin(), elem_vec.end());
      93             : }
      94             : 
      95             : void
      96       68784 : SidesToElemMap::get_sorted_vertex_ids(
      97             :   const Elem * elem,
      98             :   unsigned int side,
      99             :   std::vector<dof_id_type> & sorted_vertex_ids) const
     100             : {
     101             :   // Clear any prior data
     102        2352 :   sorted_vertex_ids.clear();
     103             : 
     104             :   // Get all vertices for this side. Note: we can stop once we reach
     105             :   // the first non-vertex node, since all vertices are numbered first.
     106      208704 :   for (const auto & n : elem->nodes_on_side(side))
     107             :   {
     108      137568 :     if (elem->is_vertex(n))
     109      142272 :       sorted_vertex_ids.push_back(elem->node_id(n));
     110             :     else
     111           0 :       break;
     112             :   }
     113             : 
     114             :   // Sort the vertex ids. The hash functions depend on the ordering
     115             :   // of the ids, so we want to be sure they are the same for every
     116             :   // Elem that touches this Side.
     117       68784 :   std::sort(sorted_vertex_ids.begin(), sorted_vertex_ids.end());
     118       68784 : }
     119             : 
     120             : } // namespace MeshTools
     121             : 
     122             : } // namespace libMesh
     123             : 

Generated by: LCOV version 1.14