LCOV - code coverage report
Current view: top level - src/utils - BoundingBoxIntersectionHelper.C (source / functions) Hit Total Coverage
Test: idaholab/moose ray_tracing: #31405 (292dce) with base fef103 Lines: 44 44 100.0 %
Date: 2025-09-04 07:56:07 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "BoundingBoxIntersectionHelper.h"
      11             : 
      12             : // libMesh includes
      13             : #include "libmesh/bounding_box.h"
      14             : #include "libmesh/face_quad4.h"
      15             : #include "libmesh/cell_hex8.h"
      16             : 
      17             : #include "TraceRayTools.h"
      18             : #include "DebugRay.h"
      19             : 
      20             : using namespace libMesh;
      21             : 
      22        1535 : BoundingBoxIntersectionHelper::BoundingBoxIntersectionHelper(const BoundingBox & bbox,
      23        1535 :                                                              const unsigned int dim)
      24        1535 :   : _comm(), _mesh(std::make_unique<Mesh>(_comm, dim))
      25             : {
      26             :   // Add the nodes that represent our bounding box
      27        1535 :   _mesh->add_point(Point(bbox.min()(0), bbox.min()(1), bbox.min()(2)), 0, 0);
      28        1535 :   _mesh->add_point(Point(bbox.max()(0), bbox.min()(1), bbox.min()(2)), 1, 0);
      29        1535 :   if (dim > 1)
      30             :   {
      31        1493 :     _mesh->add_point(Point(bbox.max()(0), bbox.max()(1), bbox.min()(2)), 2, 0);
      32        1493 :     _mesh->add_point(Point(bbox.min()(0), bbox.max()(1), bbox.min()(2)), 3, 0);
      33             : 
      34        1493 :     if (dim == 3)
      35             :     {
      36        1036 :       _mesh->add_point(Point(bbox.min()(0), bbox.min()(1), bbox.max()(2)), 4, 0);
      37        1036 :       _mesh->add_point(Point(bbox.max()(0), bbox.min()(1), bbox.max()(2)), 5, 0);
      38        1036 :       _mesh->add_point(Point(bbox.max()(0), bbox.max()(1), bbox.max()(2)), 6, 0);
      39        1036 :       _mesh->add_point(Point(bbox.min()(0), bbox.max()(1), bbox.max()(2)), 7, 0);
      40             :     }
      41             :   }
      42             : 
      43             :   // Build the element and set the nodes accordingly
      44             :   Elem * elem;
      45        1535 :   if (dim == 1)
      46          42 :     elem = Elem::build(EDGE2).release();
      47        1493 :   else if (dim == 2)
      48         457 :     elem = Elem::build(QUAD4).release();
      49             :   else
      50        1036 :     elem = Elem::build(HEX8).release();
      51        1535 :   elem = _mesh->add_elem(elem);
      52        1535 :   elem->subdomain_id() = 0;
      53             :   elem->processor_id(0);
      54        1535 :   elem->set_id() = 0;
      55       11735 :   for (unsigned int n = 0; n < _mesh->n_nodes(); ++n)
      56       10200 :     elem->set_node(n, _mesh->node_ptr(n));
      57             : 
      58             :   // All done with the mesh
      59             :   _mesh->skip_partitioning(true);
      60        1535 :   _mesh->prepare_for_use();
      61             : 
      62             :   // This costs a little bit so why not cache it now
      63        1535 :   _hmax = elem->hmax();
      64        1535 : }
      65             : 
      66             : Point
      67     1251090 : BoundingBoxIntersectionHelper::intersection(const Point & point, const Point & direction) const
      68             : {
      69             :   mooseAssert(std::abs(1.0 - direction.norm()) < TOLERANCE, "Unnormalized direction");
      70             : 
      71     1251090 :   const Elem * elem = _mesh->elem_ptr(0);
      72             : 
      73             :   // We're going to check all possible intersections and keep the one that's furthest away
      74     1251090 :   Point best_intersection_point = RayTracingCommon::invalid_point;
      75             :   Real best_intersection_distance = -std::numeric_limits<Real>::max();
      76             : 
      77             :   // For use in the intersection routines
      78             :   Point intersection_point;
      79             :   ElemExtrema intersected_extrema;
      80             :   Real intersection_distance;
      81             :   bool intersected;
      82             : 
      83             :   // Check intersection with sides
      84     8720190 :   for (const auto s : elem->side_index_range())
      85             :   {
      86     7469100 :     intersection_point = RayTracingCommon::invalid_point;
      87             :     intersected_extrema.invalidate();
      88             : 
      89     7469100 :     if (elem->dim() == 3) // 3D: Intersect HEX8
      90     7394868 :       intersected = TraceRayTools::sideIntersectedByLine<Hex8>(elem,
      91             :                                                                point,
      92             :                                                                direction,
      93             :                                                                s,
      94             :                                                                _hmax,
      95             :                                                                intersection_point,
      96             :                                                                intersection_distance,
      97             :                                                                intersected_extrema,
      98     7394868 :                                                                _hmax
      99             : #ifdef DEBUG_RAY_INTERSECTIONS
     100             :                                                                ,
     101             :                                                                false
     102             : #endif
     103             :       );
     104       74232 :     else if (elem->dim() == 2) // 2D: Intersect QUAD4
     105             :     {
     106       74016 :       intersected = TraceRayTools::sideIntersectedByLine<Quad4>(elem,
     107             :                                                                 point,
     108             :                                                                 direction,
     109             :                                                                 s,
     110             :                                                                 _hmax,
     111             :                                                                 intersection_point,
     112             :                                                                 intersection_distance,
     113             :                                                                 intersected_extrema,
     114       74016 :                                                                 _hmax
     115             : #ifdef DEBUG_RAY_INTERSECTIONS
     116             :                                                                 ,
     117             :                                                                 false
     118             : #endif
     119             :       );
     120             :     }
     121             :     else // 1D: see if side point is between point and end far away
     122             :     {
     123             :       // Dummy end point outside of the element
     124             :       const Point dummy_end = point + 1.01 * direction * _hmax;
     125             : 
     126         216 :       intersected = TraceRayTools::isWithinSegment(point, dummy_end, elem->point(s));
     127         216 :       if (intersected)
     128             :       {
     129         216 :         intersection_distance = (elem->point(s) - point).norm();
     130         216 :         intersection_point = elem->point(s);
     131             :       }
     132             :     }
     133             : 
     134     7469100 :     if (intersected && intersection_distance > best_intersection_distance)
     135             :     {
     136             :       best_intersection_distance = intersection_distance;
     137     1260660 :       best_intersection_point = intersection_point;
     138             :     }
     139             :   }
     140             : 
     141     1251090 :   return best_intersection_point;
     142             : }

Generated by: LCOV version 1.14