https://mooseframework.inl.gov
BoundingBoxIntersectionHelper.C
Go to the documentation of this file.
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 
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 
23  const unsigned int dim)
24  : _comm(), _mesh(std::make_unique<Mesh>(_comm, dim))
25 {
26  // Add the nodes that represent our bounding box
27  _mesh->add_point(Point(bbox.min()(0), bbox.min()(1), bbox.min()(2)), 0, 0);
28  _mesh->add_point(Point(bbox.max()(0), bbox.min()(1), bbox.min()(2)), 1, 0);
29  if (dim > 1)
30  {
31  _mesh->add_point(Point(bbox.max()(0), bbox.max()(1), bbox.min()(2)), 2, 0);
32  _mesh->add_point(Point(bbox.min()(0), bbox.max()(1), bbox.min()(2)), 3, 0);
33 
34  if (dim == 3)
35  {
36  _mesh->add_point(Point(bbox.min()(0), bbox.min()(1), bbox.max()(2)), 4, 0);
37  _mesh->add_point(Point(bbox.max()(0), bbox.min()(1), bbox.max()(2)), 5, 0);
38  _mesh->add_point(Point(bbox.max()(0), bbox.max()(1), bbox.max()(2)), 6, 0);
39  _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  if (dim == 1)
46  elem = Elem::build(EDGE2).release();
47  else if (dim == 2)
48  elem = Elem::build(QUAD4).release();
49  else
50  elem = Elem::build(HEX8).release();
51  elem = _mesh->add_elem(elem);
52  elem->subdomain_id() = 0;
53  elem->processor_id(0);
54  elem->set_id() = 0;
55  for (unsigned int n = 0; n < _mesh->n_nodes(); ++n)
56  elem->set_node(n, _mesh->node_ptr(n));
57 
58  // All done with the mesh
59  _mesh->skip_partitioning(true);
60  _mesh->prepare_for_use();
61 
62  // This costs a little bit so why not cache it now
63  _hmax = elem->hmax();
64 }
65 
66 Point
67 BoundingBoxIntersectionHelper::intersection(const Point & point, const Point & direction) const
68 {
69  mooseAssert(std::abs(1.0 - direction.norm()) < TOLERANCE, "Unnormalized direction");
70 
71  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  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  for (const auto s : elem->side_index_range())
85  {
86  intersection_point = RayTracingCommon::invalid_point;
87  intersected_extrema.invalidate();
88 
89  if (elem->dim() == 3) // 3D: Intersect HEX8
90  intersected = TraceRayTools::sideIntersectedByLine<Hex8>(elem,
91  point,
92  direction,
93  s,
94  _hmax,
95  intersection_point,
96  intersection_distance,
97  intersected_extrema,
98  _hmax
99 #ifdef DEBUG_RAY_INTERSECTIONS
100  ,
101  false
102 #endif
103  );
104  else if (elem->dim() == 2) // 2D: Intersect QUAD4
105  {
106  intersected = TraceRayTools::sideIntersectedByLine<Quad4>(elem,
107  point,
108  direction,
109  s,
110  _hmax,
111  intersection_point,
112  intersection_distance,
113  intersected_extrema,
114  _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  intersected = TraceRayTools::isWithinSegment(point, dummy_end, elem->point(s));
127  if (intersected)
128  {
129  intersection_distance = (elem->point(s) - point).norm();
130  intersection_point = elem->point(s);
131  }
132  }
133 
134  if (intersected && intersection_distance > best_intersection_distance)
135  {
136  best_intersection_distance = intersection_distance;
137  best_intersection_point = intersection_point;
138  }
139  }
140 
141  return best_intersection_point;
142 }
libMesh::Point intersection(const libMesh::Point &point, const libMesh::Point &direction) const
virtual Node *& set_node(const unsigned int i)
auto norm() const -> decltype(std::norm(Real()))
HEX8
IntRange< unsigned short > side_index_range() const
unsigned int dim
bool isWithinSegment(const Point &segment1, const Point &segment2, const Point &point, const Real tolerance=TRACE_TOLERANCE)
Checks whether or not a point is within a line segment.
Helper for defining if at an element&#39;s edge, vertex, or neither.
Definition: ElemExtrema.h:25
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
virtual Real hmax() const
libMesh::Real _hmax
hmax for the dummy element
dof_id_type & set_id()
QUAD4
const Point & min() const
const std::unique_ptr< libMesh::Mesh > _mesh
Dummy mesh that contains a single element used for TraceRayTools intersection methods.
auto norm(const T &a) -> decltype(std::abs(a))
BoundingBoxIntersectionHelper(const libMesh::BoundingBox &bbox, const unsigned int dim)
Constructor.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
EDGE2
subdomain_id_type subdomain_id() const
void invalidate()
Invalidates the current state.
Definition: ElemExtrema.h:87
virtual unsigned short dim() const=0
static const libMesh::Point invalid_point(invalid_distance, invalid_distance, invalid_distance)
Identifier for an invalid point.
const Point & max() const
processor_id_type processor_id() const
const Point & point(const unsigned int i) const