LCOV - code coverage report
Current view: top level - src/geom - bounding_box.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 77 85 90.6 %
Date: 2025-08-19 19:27:09 Functions: 8 9 88.9 %
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/bounding_box.h"
      22             : 
      23             : // C++ includes
      24             : #include <algorithm> // std::min_element
      25             : #include <array>
      26             : 
      27             : namespace libMesh
      28             : {
      29             : // Small helper function to make contains_point() more readable.
      30       35799 : inline bool is_between(Real min, Real check, Real max)
      31             : {
      32      405087 :   return min <= check && check <= max;
      33             : }
      34             : 
      35      141776 : bool BoundingBox::contains_point (const Point & p) const
      36             : {
      37             :   // Make local variables first to make things more clear in a moment
      38      141776 :   Real my_min_x = this->first(0);
      39      141776 :   Real my_max_x = this->second(0);
      40      141776 :   bool x_int = is_between(my_min_x, p(0), my_max_x);
      41             : 
      42       11752 :   bool intersection_true = x_int;
      43             : 
      44             : #if LIBMESH_DIM > 1
      45      141776 :   Real my_min_y = this->first(1);
      46      141776 :   Real my_max_y = this->second(1);
      47      141776 :   bool y_int = is_between(my_min_y, p(1), my_max_y);
      48             : 
      49      141776 :   intersection_true = intersection_true && y_int;
      50             : #endif
      51             : 
      52             : 
      53             : #if LIBMESH_DIM > 2
      54      141776 :   Real my_min_z = this->first(2);
      55      141776 :   Real my_max_z = this->second(2);
      56      141776 :   bool z_int = is_between(my_min_z, p(2), my_max_z);
      57             : 
      58      141776 :   intersection_true = intersection_true && z_int;
      59             : #endif
      60             : 
      61      141776 :   return intersection_true;
      62             : }
      63             : 
      64             : 
      65             : 
      66        2172 : Real BoundingBox::max_size() const
      67             : {
      68        2172 :   Real size = 0;
      69        8688 :   for (unsigned int d = 0; d != LIBMESH_DIM; ++d)
      70             :     {
      71        6516 :       Real sized = this->second(d) - this->first(d);
      72        7059 :       if (!libmesh_isinf(sized) &&
      73       13032 :           this->second(d) != std::numeric_limits<Real>::max() &&
      74         543 :           this->first(d) != -std::numeric_limits<Real>::max())
      75        6516 :         size = std::max(size, sized);
      76             :     }
      77        2172 :   return size;
      78             : }
      79             : 
      80             : 
      81             : 
      82        2172 : bool BoundingBox::contains_point
      83             :   (const Point & p, Real abs_tol, Real rel_tol) const
      84             : {
      85         181 :   libmesh_assert_greater_equal(abs_tol, Real(0));
      86         181 :   libmesh_assert_greater_equal(rel_tol, Real(0));
      87             : 
      88             :   // Just use the other contains_point overload
      89         181 :   libmesh_assert_greater(rel_tol+abs_tol, Real(0));
      90             : 
      91             :   // Find absolute tolerance from relative tolerance
      92        2172 :   const Real tol = std::max(abs_tol, this->max_size()*rel_tol);
      93             : 
      94             :   // Make local variables first to make things more clear in a moment
      95        2172 :   const Real my_min_x = this->first(0) - tol;
      96        2172 :   const Real my_max_x = this->second(0) + tol;
      97        2172 :   const bool x_int = is_between(my_min_x, p(0), my_max_x);
      98             : 
      99         181 :   bool intersection_true = x_int;
     100             : 
     101             : #if LIBMESH_DIM > 1
     102        2172 :   const Real my_min_y = this->first(1) - tol;
     103        2172 :   const Real my_max_y = this->second(1) + tol;
     104        2172 :   const bool y_int = is_between(my_min_y, p(1), my_max_y);
     105             : 
     106        2172 :   intersection_true = intersection_true && y_int;
     107             : #endif
     108             : 
     109             : 
     110             : #if LIBMESH_DIM > 2
     111        2172 :   const Real my_min_z = this->first(2) - tol;
     112        2172 :   const Real my_max_z = this->second(2) + tol;
     113        2172 :   const bool z_int = is_between(my_min_z, p(2), my_max_z);
     114             : 
     115        2172 :   intersection_true = intersection_true && z_int;
     116             : #endif
     117             : 
     118        2172 :   return intersection_true;
     119             : }
     120             : 
     121             : 
     122             : 
     123           0 : void BoundingBox::intersect_with (const BoundingBox & other_box)
     124             : {
     125           0 :   this->first(0)  = std::max(this->first(0),  other_box.first(0));
     126           0 :   this->second(0) = std::min(this->second(0), other_box.second(0));
     127             : 
     128             : #if LIBMESH_DIM > 1
     129           0 :   this->first(1)  = std::max(this->first(1),  other_box.first(1));
     130           0 :   this->second(1) = std::min(this->second(1), other_box.second(1));
     131             : #endif
     132             : 
     133             : #if LIBMESH_DIM > 2
     134           0 :   this->first(2)  = std::max(this->first(2),  other_box.first(2));
     135           0 :   this->second(2) = std::min(this->second(2), other_box.second(2));
     136             : #endif
     137           0 : }
     138             : 
     139             : 
     140    63996743 : void BoundingBox::union_with (const BoundingBox & other_box)
     141             : {
     142    63996743 :   this->first(0)  = std::min(this->first(0),  other_box.first(0));
     143    63996743 :   this->second(0) = std::max(this->second(0), other_box.second(0));
     144             : 
     145             : #if LIBMESH_DIM > 1
     146    63996743 :   this->first(1)  = std::min(this->first(1),  other_box.first(1));
     147    63996743 :   this->second(1) = std::max(this->second(1), other_box.second(1));
     148             : #endif
     149             : 
     150             : #if LIBMESH_DIM > 2
     151    63996743 :   this->first(2)  = std::min(this->first(2),  other_box.first(2));
     152    63996743 :   this->second(2) = std::max(this->second(2), other_box.second(2));
     153             : #endif
     154    63996743 : }
     155             : 
     156             : 
     157             : 
     158        1136 : Real BoundingBox::signed_distance(const Point & p) const
     159             : {
     160        1136 :   if (contains_point(p))
     161             :     {
     162             :       // Sign convention: if Point is inside the bbox, the distance is
     163             :       // negative. We then find the smallest distance to the different
     164             :       // sides of the box and return that.
     165         426 :       Real min_dist = std::numeric_limits<Real>::max();
     166             : 
     167        1704 :       for (unsigned int dir=0; dir<LIBMESH_DIM; ++dir)
     168             :         {
     169        1314 :           min_dist = std::min(min_dist, std::abs(p(dir) - second(dir)));
     170        1452 :           min_dist = std::min(min_dist, std::abs(p(dir) - first(dir)));
     171             :         }
     172             : 
     173         426 :       return -min_dist;
     174             :     }
     175             :   else // p is outside the box
     176             :     {
     177         710 :       Real dx[3] = {0., 0., 0.};
     178             : 
     179             :       // Compute distance "above"/"below" the box in each
     180             :       // direction. If the point is somewhere in between the (min,
     181             :       // max) values of the box, dx is 0.
     182        2840 :       for (unsigned int dir=0; dir<LIBMESH_DIM; ++dir)
     183             :         {
     184        2130 :           if (p(dir) > second(dir))
     185         639 :             dx[dir] = p(dir) - second(dir);
     186        1491 :           else if (p(dir) < first(dir))
     187         639 :             dx[dir] = p(dir) - first(dir);
     188             :         }
     189             : 
     190         710 :       return std::sqrt(dx[0]*dx[0] + dx[1]*dx[1] + dx[2]*dx[2]);
     191             :     }
     192             : }
     193             : 
     194             : 
     195       11265 : void BoundingBox::scale(const Real factor)
     196             : {
     197             :   Real append;
     198       45060 :   for (unsigned int dim = 0; dim != LIBMESH_DIM; ++dim)
     199             :   {
     200       36627 :     if (this->first(dim) != std::numeric_limits<Real>::max() &&
     201       33795 :         this->second(dim) != -std::numeric_limits<Real>::max())
     202             :     {
     203        2832 :       libmesh_assert_greater_equal(this->second(dim), this->first(dim));
     204       33795 :       append = (this->second(dim) - this->first(dim)) * factor;
     205       33795 :       this->first(dim) -= append;
     206       33795 :       this->second(dim) += append;
     207             :     }
     208             :   }
     209       11265 : }
     210             : 
     211             : 
     212          12 : void BoundingBox::print(std::ostream & os) const
     213             : {
     214          13 :   os << "(min=" << this->min() << ", max=" << this->max() << ")";
     215          12 : }
     216             : 
     217             : } // namespace libMesh

Generated by: LCOV version 1.14