https://mooseframework.inl.gov
Loading...
Searching...
No Matches
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
20using 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
67BoundingBoxIntersectionHelper::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}
unsigned int dim
libMesh::Point intersection(const libMesh::Point &point, const libMesh::Point &direction) const
libMesh::Real _hmax
hmax for the dummy element
const std::unique_ptr< libMesh::Mesh > _mesh
Dummy mesh that contains a single element used for TraceRayTools intersection methods.
BoundingBoxIntersectionHelper(const libMesh::BoundingBox &bbox, const unsigned int dim)
Constructor.
const Point & max() const
const Point & min() const
processor_id_type processor_id() const
dof_id_type & set_id()
virtual Node *& set_node(const unsigned int i)
const Point & point(const unsigned int i) const
virtual unsigned short dim() const=0
subdomain_id_type subdomain_id() const
virtual Real hmax() const
IntRange< unsigned short > side_index_range() const
auto norm() const
static const libMesh::Point invalid_point(invalid_distance, invalid_distance, invalid_distance)
Identifier for an invalid point.
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.
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
static constexpr Real TOLERANCE
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Helper for defining if at an element's edge, vertex, or neither.
Definition ElemExtrema.h:26
void invalidate()
Invalidates the current state.
Definition ElemExtrema.h:87