LCOV - code coverage report
Current view: top level - src/utils - location_maps.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 49 67 73.1 %
Date: 2025-08-19 19:27:09 Functions: 6 12 50.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             : 
      19             : 
      20             : // Local Includes
      21             : #include "libmesh/elem.h"
      22             : #include "libmesh/libmesh_logging.h"
      23             : #include "libmesh/location_maps.h"
      24             : #include "libmesh/mesh_base.h"
      25             : #include "libmesh/node.h"
      26             : #include "libmesh/parallel.h"
      27             : 
      28             : // C++ Includes
      29             : #include <limits>
      30             : #include <utility>
      31             : 
      32             : namespace
      33             : {
      34             : using libMesh::Real;
      35             : 
      36             : // 10 bits per coordinate, to work with 32+ bit machines
      37             : const unsigned int chunkmax = 1024;
      38             : const Real chunkfloat = 1024.0;
      39             : }
      40             : 
      41             : 
      42             : 
      43             : namespace libMesh
      44             : {
      45             : 
      46             : template <typename T>
      47          71 : void LocationMap<T>::init(MeshBase & mesh)
      48             : {
      49             :   // This function must be run on all processors at once
      50             :   // for non-serial meshes
      51          71 :   if (!mesh.is_serial())
      52           0 :     libmesh_parallel_only(mesh.comm());
      53             : 
      54           4 :   LOG_SCOPE("init()", "LocationMap");
      55             : 
      56             :   // Clear the old map
      57           2 :   _map.clear();
      58             : 
      59             :   // Cache a bounding box
      60          71 :   _lower_bound.clear();
      61          71 :   _lower_bound.resize(LIBMESH_DIM, std::numeric_limits<Real>::max());
      62          71 :   _upper_bound.clear();
      63          71 :   _upper_bound.resize(LIBMESH_DIM, -std::numeric_limits<Real>::max());
      64             : 
      65       33555 :   for (auto & node : mesh.node_ptr_range())
      66       69440 :     for (unsigned int i=0; i != LIBMESH_DIM; ++i)
      67             :       {
      68             :         // Expand the bounding box if necessary
      69       52368 :         _lower_bound[i] = std::min(_lower_bound[i],
      70       54138 :                                    (*node)(i));
      71       52080 :         _upper_bound[i] = std::max(_upper_bound[i],
      72        4116 :                                    (*node)(i));
      73             :       }
      74             : 
      75             :   // On a parallel mesh we might not yet have a full bounding box
      76          71 :   if (!mesh.is_serial())
      77             :     {
      78          64 :       mesh.comm().min(_lower_bound);
      79          64 :       mesh.comm().max(_upper_bound);
      80             :     }
      81             : 
      82          71 :   this->fill(mesh);
      83          71 : }
      84             : 
      85             : 
      86             : 
      87             : template <typename T>
      88       17360 : void LocationMap<T>::insert(T & t)
      89             : {
      90       17360 :   this->_map.emplace(this->key(this->point_of(t)), &t);
      91       17360 : }
      92             : 
      93             : 
      94             : 
      95             : template <>
      96       43848 : Point LocationMap<Node>::point_of(const Node & node) const
      97             : {
      98       43848 :   return node;
      99             : }
     100             : 
     101             : 
     102             : 
     103             : template <>
     104           0 : Point LocationMap<Elem>::point_of(const Elem & elem) const
     105             : {
     106           0 :   return elem.vertex_average();
     107             : }
     108             : 
     109             : 
     110             : 
     111             : template <typename T>
     112       13244 : T * LocationMap<T>::find(const Point & p,
     113             :                          const Real tol)
     114             : {
     115         686 :   LOG_SCOPE("find()", "LocationMap");
     116             : 
     117             :   // Look for a likely key in the multimap
     118       13244 :   unsigned int pointkey = this->key(p);
     119             : 
     120             :   // Look for the exact key first
     121       13244 :   for (const auto & pr : as_range(_map.equal_range(pointkey)))
     122       13587 :     if (p.absolute_fuzzy_equals(this->point_of(*(pr.second)), tol))
     123       13244 :       return pr.second;
     124             : 
     125             :   // Look for neighboring bins' keys next
     126           0 :   for (int xoffset = -1; xoffset != 2; ++xoffset)
     127             :     {
     128           0 :       for (int yoffset = -1; yoffset != 2; ++yoffset)
     129             :         {
     130           0 :           for (int zoffset = -1; zoffset != 2; ++zoffset)
     131             :             {
     132           0 :               auto key_pos = _map.equal_range(pointkey +
     133           0 :                                               xoffset*chunkmax*chunkmax +
     134           0 :                                               yoffset*chunkmax +
     135           0 :                                               zoffset);
     136           0 :               for (const auto & pr : as_range(key_pos))
     137           0 :                 if (p.absolute_fuzzy_equals(this->point_of(*(pr.second)), tol))
     138           0 :                   return pr.second;
     139             :             }
     140             :         }
     141             :     }
     142             : 
     143           0 :   return nullptr;
     144             : }
     145             : 
     146             : 
     147             : 
     148             : template <typename T>
     149       30604 : unsigned int LocationMap<T>::key(const Point & p)
     150             : {
     151        1029 :   Real xscaled = 0., yscaled = 0., zscaled = 0.;
     152             : 
     153       30604 :   Real deltax = _upper_bound[0] - _lower_bound[0];
     154             : 
     155       30604 :   if (std::abs(deltax) > TOLERANCE)
     156       30604 :     xscaled = (p(0) - _lower_bound[0])/deltax;
     157             : 
     158             :   // Only check y-coords if libmesh is compiled with LIBMESH_DIM>1
     159             : #if LIBMESH_DIM > 1
     160       30604 :   Real deltay = _upper_bound[1] - _lower_bound[1];
     161             : 
     162       30604 :   if (std::abs(deltay) > TOLERANCE)
     163       30604 :     yscaled = (p(1) - _lower_bound[1])/deltay;
     164             : #endif
     165             : 
     166             :   // Only check z-coords if libmesh is compiled with LIBMESH_DIM>2
     167             : #if LIBMESH_DIM > 2
     168       30604 :   Real deltaz = _upper_bound[2] - _lower_bound[2];
     169             : 
     170       30604 :   if (std::abs(deltaz) > TOLERANCE)
     171       30604 :     zscaled = (p(2) - _lower_bound[2])/deltaz;
     172             : #endif
     173             : 
     174       30604 :   unsigned int n0 = static_cast<unsigned int> (chunkfloat * xscaled),
     175       30604 :     n1 = static_cast<unsigned int> (chunkfloat * yscaled),
     176       30604 :     n2 = static_cast<unsigned int> (chunkfloat * zscaled);
     177             : 
     178       30604 :   return chunkmax*chunkmax*n0 + chunkmax*n1 + n2;
     179             : }
     180             : 
     181             : 
     182             : 
     183             : template <>
     184          71 : void LocationMap<Node>::fill(MeshBase & mesh)
     185             : {
     186             :   // Populate the nodes map
     187       33488 :   for (auto & node : mesh.node_ptr_range())
     188       17427 :     this->insert(*node);
     189          71 : }
     190             : 
     191             : 
     192             : 
     193             : template <>
     194           0 : void LocationMap<Elem>::fill(MeshBase & mesh)
     195             : {
     196             :   // Populate the elem map
     197           0 :   for (auto & elem : mesh.active_element_ptr_range())
     198           0 :     this->insert(*elem);
     199           0 : }
     200             : 
     201             : 
     202             : 
     203             : template class LIBMESH_EXPORT LocationMap<Elem>;
     204             : template class LIBMESH_EXPORT LocationMap<Node>;
     205             : 
     206             : } // namespace libMesh

Generated by: LCOV version 1.14