https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Enumerations | Functions | Variables
TraceRayTools Namespace Reference

Enumerations

enum  SegmentVertices { SEGMENT_VERTEX_0 = 0 , SEGMENT_VERTEX_1 = 1 , SEGMENT_VERTEX_NONE = 7 }
 Enum for the possible vertices on a segment used in lineLineIntersect2D() More...
 

Functions

bool lineLineIntersect2D (const Point &start, const Point &direction, const Real length, const Point &v0, const Point &v1, Point &intersection_point, Real &intersection_distance, SegmentVertices &segment_vertex #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 Checks for the intersection of the line u0 -> u1 with the line v0 -> v1, where u0 = start and u1 = start + direction * length.
 
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.
 
bool isWithinSegment (const Point &segment1, const Point &segment2, const Real segment_length, const Point &point, const Real tolerance=TRACE_TOLERANCE)
 Checks whether or not a point is within a line segment.
 
void findPointNeighbors (const Elem *const elem, const Point &point, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &neighbor_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &untested_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &next_untested_set, std::vector< const Elem * > active_neighbor_children, std::vector< NeighborInfo > &info)
 Rewrite of the find_point_neighbors function in libMesh, instead using a statically allocated set: returns the active point neighbors at p within elem.
 
void findNodeNeighbors (const Elem *const elem, const Node *const node, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &neighbor_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &untested_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &next_untested_set, std::vector< const Elem * > active_neighbor_children, std::vector< NeighborInfo > &info)
 
void findEdgeNeighbors (const Elem *const elem, const Node *const node1, const Node *const node2, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &neighbor_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &untested_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &next_untested_set, std::vector< const Elem * > active_neighbor_children, std::vector< NeighborInfo > &info)
 
template<typename KeepFunctor >
void findNeighbors (const Elem *const elem, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &neighbor_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &untested_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &next_untested_set, std::vector< const Elem * > active_neighbor_children, KeepFunctor &keep_functor)
 More generalized form of the find_point_neighbors function in libMesh.
 
template<typename T >
bool findEdgeNeighborsWithinEdgeInternal (const Elem *const candidate, const Elem *const elem, const Node *const vertex1, const Node *const vertex2, const Real edge_length, std::vector< NeighborInfo > &info)
 
const Elem * childContainingPointOnSide (const Elem *elem, const Point &point, const unsigned short side)
 Find the child of an elem that contains a point on a specified side of elem.
 
const Elem * getActiveNeighbor (const Elem *elem, const unsigned short side, const Point &point)
 Get the active neighbor on side of elem that contains point.
 
bool intersectTriangle (const Point &start, const Point &direction, const Elem *const elem, const unsigned short v0, const unsigned short v1, const unsigned short v2, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 Checks for the intersection of a ray and a triangular face.
 
bool intersectQuad (const Point &start, const Point &direction, const Elem *const elem, const unsigned short v00, const unsigned short v10, const unsigned short v11, const unsigned short v01, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 Checks for the intersection of a ray and a quadrilateral, numbered as such:
 
template<typename T >
std::enable_if< std::is_base_of< libMesh::Face, T >::value, bool >::type sideIntersectedByLine (const Elem *elem, const Point &start_point, const Point &direction, const unsigned short side, const Real max_length, Point &intersection_point, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 SFINAE typed object for checking the intersection of a line segment with the face of a Face typed element, i.e., the intersection with the edge of a 2D element.
 
template<typename T >
std::enable_if< std::is_base_of< Hex, T >::value, bool >::type sideIntersectedByLine (const Elem *elem, const Point &start_point, const Point &direction, const unsigned short side, const Real, Point &intersection_point, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 SFINAE typed object for checking the intersection of a line segment with the face of a Hex typed element.
 
template<typename T >
std::enable_if< std::is_base_of< Tet, T >::value, bool >::type sideIntersectedByLine (const Elem *elem, const Point &start_point, const Point &direction, const unsigned short side, const Real, Point &intersection_point, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 SFINAE typed object for checking the intersection of a line segment with the face of a Tet typed element.
 
template<typename T >
std::enable_if< std::is_base_of< libMesh::Pyramid, T >::value, bool >::type sideIntersectedByLine (const Elem *elem, const Point &start_point, const Point &direction, const unsigned short side, const Real, Point &intersection_point, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 SFINAE typed object for checking the intersection of a line segment with the face of a Pyramid typed element.
 
template<typename T >
std::enable_if< std::is_base_of< libMesh::Prism, T >::value, bool >::type sideIntersectedByLine (const Elem *elem, const Point &start_point, const Point &direction, const unsigned short side, const Real, Point &intersection_point, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 SFINAE typed object for checking the intersection of a line segment with the face of a Prism typed element.
 
bool isTraceableElem (const Elem *elem)
 
bool isAdaptivityTraceableElem (const Elem *elem)
 
unsigned short atVertex (const Elem *elem, const Point &point)
 Determines if a point is at a vertex of an element.
 
unsigned short atVertexOnSide (const Elem *elem, const Point &point, const unsigned short side)
 Determines if a point is at a vertex on the side of en element.
 
template<typename T >
std::enable_if<!std::is_base_of< libMesh::Pyramid, T >::value &&!std::is_base_of< libMesh::Prism, T >::value, unsignedshort >::type nodesPerSide (const unsigned short)
 Returns the number of nodes on a side for an Elem that is not a Pyramid or Prism.
 
template<typename T >
std::enable_if< std::is_base_of< Pyramid, T >::value, unsignedshort >::type nodesPerSide (const unsigned short side)
 Returns the number of nodes on a side on a Pyramid elem.
 
template<typename T >
std::enable_if< std::is_base_of< libMesh::Prism, T >::value, unsignedshort >::type nodesPerSide (const unsigned short side)
 Returns the number of nodes on a side on a Prism elem.
 
template<typename T >
std::enable_if<!std::is_base_of< Edge, T >::value, unsignedshort >::type atVertexOnSideTempl (const Elem *elem, const Point &point, const unsigned short side)
 Determines if a point is at a vertex on the side of an element.
 
template<typename T >
std::enable_if< std::is_base_of< Edge, T >::value, unsignedshort >::type atVertexOnSideTempl (const Elem *elem, const Point &point, const unsigned short side)
 Determines if a point is at a vertex on the side of an element.
 
template<typename T >
bool withinEdgeTempl (const Elem *elem, const Point &point, ElemExtrema &extrema, const Real tolerance=TRACE_TOLERANCE)
 Determines if a point is within edge on an element.
 
bool withinEdge (const Elem *elem, const Point &point, ElemExtrema &extrema, const Real tolerance=TRACE_TOLERANCE)
 Determines if a point is within an edge on an element.
 
bool withinEdgeOnSide (const Elem *const elem, const Point &point, const unsigned short side, ElemExtrema &extrema)
 Determines if a point is within an edge on the side of an element.
 
bool withinExtremaOnSide (const Elem *const elem, const Point &point, const unsigned short side, const unsigned int dim, ElemExtrema &extrema)
 Determines if a point is within an Elem's extrema (at vertex/within edge) on a side.
 
template<typename T >
std::enable_if< std::is_base_of< libMesh::Cell, T >::value, bool >::type withinEdgeOnSideTempl (const Elem *const elem, const Point &point, const unsigned short side, ElemExtrema &extrema)
 Determines if a point is within an edge on the side of an element.
 
template<typename T >
std::enable_if<!std::is_base_of< libMesh::Cell, T >::value, bool >::type withinEdgeOnSideTempl (const Elem *const, const Point &, const unsigned short, ElemExtrema &)
 Determines if a point is within an edge on the side of an element.
 
bool onBoundingBoxBoundary (const BoundingBox &bbox, const Point &point, const unsigned int dim, const Real tolerance)
 Whether or not point is on the boundary (min/max) of bbox.
 
bool lineLineIntersect2D (const Point &start, const Point &direction, const Real length, const Point &v0, const Point &v1, Point &intersection_point, Real &intersection_distance, SegmentVertices &segment_vertex #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 
void findPointNeighbors (const Elem *const elem, const Point &point, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &neighbor_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &untested_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &next_untested_set, std::vector< const Elem * > active_neighbor_children, std::vector< NeighborInfo > &info)
 
void findNodeNeighbors (const Elem *const elem, const Node *const node, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &neighbor_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &untested_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &next_untested_set, std::vector< const Elem * > active_neighbor_children, std::vector< NeighborInfo > &info)
 
void findEdgeNeighbors (const Elem *const elem, const Node *const node1, const Node *const node2, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &neighbor_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &untested_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &next_untested_set, std::vector< const Elem * > active_neighbor_children, std::vector< NeighborInfo > &info)
 
const ElemchildContainingPointOnSide (const Elem *elem, const Point &point, const unsigned short side)
 
const ElemgetActiveNeighbor (const Elem *elem, const unsigned short side, const Point &point)
 
bool intersectTriangle (const Point &start, const Point &direction, const Elem *const elem, const unsigned short v0, const unsigned short v1, const unsigned short v2, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 
bool intersectQuad (const Point &start, const Point &direction, const Elem *const elem, const unsigned short v00, const unsigned short v10, const unsigned short v11, const unsigned short v01, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
 
bool isTraceableElem (const Elem *elem)
 
bool isAdaptivityTraceableElem (const Elem *elem)
 
unsigned short atVertex (const Elem *elem, const Point &point)
 
template<typename T >
bool withinEdgeTempl (const Elem *elem, const Point &point, ElemExtrema &extrema, const Real tolerance)
 
bool withinEdge (const Elem *elem, const Point &point, ElemExtrema &extrema, const Real tolerance)
 
unsigned short atVertexOnSide (const Elem *elem, const Point &point, const unsigned short side)
 
template<typename T >
std::enable_if<!std::is_base_of< Edge, T >::value, unsignedshort >::type atVertexOnSideTempl (const Elem *elem, const Point &point, const unsigned short side)
 
template<typename T >
std::enable_if< std::is_base_of< Edge, T >::value, unsignedshort >::type atVertexOnSideTempl (const Elem *elem, const Point &point, const unsigned short side)
 
bool withinEdgeOnSide (const Elem *const elem, const Point &point, const unsigned short side, ElemExtrema &extrema)
 
template<typename T >
std::enable_if< std::is_base_of< Cell, T >::value, bool >::type withinEdgeOnSideTempl (const Elem *const elem, const Point &point, const unsigned short side, ElemExtrema &extrema)
 
bool withinExtremaOnSide (const Elem *const elem, const Point &point, const unsigned short side, const unsigned int dim, ElemExtrema &extrema)
 
bool isWithinSegment (const Point &segment1, const Point &segment2, const Point &point, const Real tolerance)
 
bool isWithinSegment (const Point &segment1, const Point &segment2, const Real segment_length, const Point &point, const Real tolerance)
 
bool onBoundingBoxBoundary (const BoundingBox &bbox, const Point &point, const unsigned int dim, const Real tolerance)
 

Variables

const std::set< intTRACEABLE_ELEMTYPES
 The element types that are traceable.
 
const std::set< intADAPTIVITY_TRACEABLE_ELEMTYPES = {QUAD4, HEX8, TRI3, TET4, EDGE2}
 The element types that are traceable with adaptivity.
 
const Real TRACE_TOLERANCE = 1e-8
 The standard tolerance to use in tracing.
 
const Real LOOSE_TRACE_TOLERANCE = 1e-5
 Looser tolerance for use in error checking in difficult situations.
 
const int INVALID_INT = std::numeric_limits<int>::max()
 Value for an invalid integer.
 

Enumeration Type Documentation

◆ SegmentVertices

Enum for the possible vertices on a segment used in lineLineIntersect2D()

Enumerator
SEGMENT_VERTEX_0 
SEGMENT_VERTEX_1 
SEGMENT_VERTEX_NONE 

Definition at line 58 of file TraceRayTools.h.

Function Documentation

◆ atVertex() [1/2]

unsigned short TraceRayTools::atVertex ( const Elem *  elem,
const Point &  point 
)

Determines if a point is at a vertex of an element.

Parameters
elemThe element
pointThe point
Returns
The local vertex ID the point is at, if any (invalid_point otherwise)

Referenced by TraceRay::applyOnInternalBoundary(), TEST(), and TraceRay::trace().

◆ atVertex() [2/2]

unsigned short TraceRayTools::atVertex ( const Elem elem,
const Point point 
)

Definition at line 563 of file TraceRayTools.C.

564{
565 for (unsigned int v = 0; v < elem->n_vertices(); ++v)
566 if (elem->point(v).absolute_fuzzy_equals(point, TRACE_TOLERANCE))
567 return v;
568
570}
const double v
virtual unsigned int n_vertices() const=0
const Point & point(const unsigned int i) const
bool absolute_fuzzy_equals(const TypeVector< Real > &rhs, Real tol=TOLERANCE) const
static const unsigned short invalid_vertex
Identifier for an invalid vertex index.

◆ atVertexOnSide() [1/2]

unsigned short TraceRayTools::atVertexOnSide ( const Elem *  elem,
const Point &  point,
const unsigned short  side 
)

Determines if a point is at a vertex on the side of en element.

Parameters
elemThe element
pointThe point
sideThe side
Returns
The local vertex ID the point is at, if any (invalid_point otherwise)

Referenced by TEST(), TraceRay::trace(), and withinExtremaOnSide().

◆ atVertexOnSide() [2/2]

unsigned short TraceRayTools::atVertexOnSide ( const Elem elem,
const Point point,
const unsigned short  side 
)

Definition at line 628 of file TraceRayTools.C.

629{
630 switch (elem->type())
631 {
632 case HEX8:
633 case HEX20:
634 case HEX27:
635 return atVertexOnSideTempl<Hex8>(elem, point, side);
636 case QUAD4:
637 case QUAD8:
638 case QUAD9:
639 return atVertexOnSideTempl<Quad4>(elem, point, side);
640 case TRI3:
641 case TRI6:
642 case TRI7:
643 return atVertexOnSideTempl<Tri3>(elem, point, side);
644 case TET4:
645 case TET10:
646 case TET14:
647 return atVertexOnSideTempl<Tet4>(elem, point, side);
648 case PYRAMID5:
649 case PYRAMID13:
650 case PYRAMID14:
651 return atVertexOnSideTempl<Pyramid5>(elem, point, side);
652 case PRISM6:
653 case PRISM15:
654 case PRISM18:
655 return atVertexOnSideTempl<Prism6>(elem, point, side);
656 case EDGE2:
657 case EDGE3:
658 case EDGE4:
659 return atVertexOnSideTempl<Edge2>(elem, point, side);
660 default:
661 mooseError("Element type ",
663 " not supported in TraceRayTools::atVertexOnSide()");
664 }
665
667}
void mooseError(Args &&... args)
virtual ElemType type() const=0
std::string enum_to_string(const T e)

◆ atVertexOnSideTempl() [1/4]

template<typename T >
std::enable_if<!std::is_base_of< Edge, T >::value, unsignedshort >::type TraceRayTools::atVertexOnSideTempl ( const Elem *  elem,
const Point &  point,
const unsigned short  side 
)

Determines if a point is at a vertex on the side of an element.

SFINAE here makes this method available for only 2D/3D elem types (not edges)

The template argument should be the first order type of the elem - this is used to access the vertex mappings for said element without calling any virtuals

Parameters
elemThe element
pointThe point
sideThe side
Returns
The local vertex ID the point is at, if any (invalid_point otherwise)

◆ atVertexOnSideTempl() [2/4]

template<typename T >
std::enable_if< std::is_base_of< Edge, T >::value, unsignedshort >::type TraceRayTools::atVertexOnSideTempl ( const Elem *  elem,
const Point &  point,
const unsigned short  side 
)

Determines if a point is at a vertex on the side of an element.

SFINAE here makes this method available for only 1D elem types (edges)

The template argument should be the first order type of the elem - this is used to access the vertex mappings for said element without calling any virtuals

Parameters
elemThe element
pointThe point
sideThe side
Returns
The local vertex ID the point is at, if any (invalid_point otherwise)

◆ atVertexOnSideTempl() [3/4]

template<typename T >
std::enable_if<!std::is_base_of< Edge, T >::value, unsignedshort >::type TraceRayTools::atVertexOnSideTempl ( const Elem elem,
const Point point,
const unsigned short  side 
)

Definition at line 671 of file TraceRayTools.C.

672{
673 mooseAssert(side < elem->n_sides(), "Invalid side");
674 mooseAssert(elem->side_ptr(side)->close_to_point(point, LOOSE_TRACE_TOLERANCE),
675 "Side does not contain point");
676
677 for (int i = 0; i < nodesPerSide<T>(side); ++i)
678 if (elem->point(T::side_nodes_map[side][i]).absolute_fuzzy_equals(point, TRACE_TOLERANCE))
679 return T::side_nodes_map[side][i];
680
682}
virtual std::unique_ptr< Elem > side_ptr(unsigned int i)=0

◆ atVertexOnSideTempl() [4/4]

template<typename T >
std::enable_if< std::is_base_of< Edge, T >::value, unsignedshort >::type TraceRayTools::atVertexOnSideTempl ( const Elem elem,
const Point point,
const unsigned short  side 
)

Definition at line 686 of file TraceRayTools.C.

687{
688 mooseAssert(side < elem->n_sides(), "Invalid side");
689 mooseAssert(elem->side_ptr(side)->close_to_point(point, LOOSE_TRACE_TOLERANCE),
690 "Side does not contain point");
691
692 if (elem->point(side).absolute_fuzzy_equals(point, TRACE_TOLERANCE))
693 return side;
694
696}

◆ childContainingPointOnSide() [1/2]

const Elem * TraceRayTools::childContainingPointOnSide ( const Elem *  elem,
const Point &  point,
const unsigned short  side 
)

Find the child of an elem that contains a point on a specified side of elem.

Parameters
elemThe parent element
pointThe point that is in elem
sideThe side that point is on in elem
Returns
The child that contains the point

Referenced by childContainingPointOnSide(), and getActiveNeighbor().

◆ childContainingPointOnSide() [2/2]

const Elem * TraceRayTools::childContainingPointOnSide ( const Elem elem,
const Point point,
const unsigned short  side 
)

Definition at line 329 of file TraceRayTools.C.

330{
331 mooseAssert(!elem->active(), "Should be inactive");
332 mooseAssert(elem->side_ptr(side)->contains_point(point), "Side should contain point");
333
334 for (unsigned int c = 0; c < elem->n_children(); ++c)
335 {
336 if (!elem->is_child_on_side(c, side))
337 continue;
338
339 const auto child = elem->child_ptr(c);
340 // Experience shows that we need to loosen this tolerance just a little
341 // The default is libMesh::TOLERANCE = 1e-6
342 if (child->close_to_point(point, 5.e-5))
343 {
344 if (child->active())
345 return child;
346 else
347 return childContainingPointOnSide(child, point, side);
348 }
349 }
350
351 mooseError("Failed to find child containing point on side");
352}
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const=0
bool active() const
const Elem * child_ptr(unsigned int i) const
virtual unsigned int n_children() const=0
const Elem * childContainingPointOnSide(const Elem *elem, const Point &point, const unsigned short side)
Find the child of an elem that contains a point on a specified side of elem.

◆ findEdgeNeighbors() [1/2]

void TraceRayTools::findEdgeNeighbors ( const Elem *const  elem,
const Node *const  node1,
const Node *const  node2,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  neighbor_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  untested_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  next_untested_set,
std::vector< const Elem * >  active_neighbor_children,
std::vector< NeighborInfo > &  info 
)

◆ findEdgeNeighbors() [2/2]

void TraceRayTools::findEdgeNeighbors ( const Elem *const  elem,
const Node *const  node1,
const Node *const  node2,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  neighbor_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  untested_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  next_untested_set,
std::vector< const Elem * >  active_neighbor_children,
std::vector< NeighborInfo > &  info 
)

Definition at line 254 of file TraceRayTools.C.

263{
264 mooseAssert(elem->get_node_index(node1) != libMesh::invalid_uint, "Doesn't contain node");
265 mooseAssert(elem->get_node_index(node2) != libMesh::invalid_uint, "Doesn't contain node");
266
267 info.clear();
268
269 // The length for this edge used for checking if a point is contained within said edge
270 const Real edge_length = ((Point)*node1 - (Point)*node2).norm();
271
272 // Lambda that returns whether or not a candidate element contains an edge that is within the
273 // target edge defined by node1 and node2. Also fills "info" if a match is found
274 auto within_edge = [&elem, &node1, &node2, &edge_length, &info](const Elem * const candidate)
275 {
276 switch (candidate->type())
277 {
278 case HEX8:
279 return findEdgeNeighborsWithinEdgeInternal<Hex8>(
280 candidate, elem, node1, node2, edge_length, info);
281 case TET4:
282 return findEdgeNeighborsWithinEdgeInternal<Tet4>(
283 candidate, elem, node1, node2, edge_length, info);
284 case PYRAMID5:
285 return findEdgeNeighborsWithinEdgeInternal<Pyramid5>(
286 candidate, elem, node1, node2, edge_length, info);
287 case PRISM6:
288 return findEdgeNeighborsWithinEdgeInternal<Prism6>(
289 candidate, elem, node1, node2, edge_length, info);
290 case HEX20:
291 return findEdgeNeighborsWithinEdgeInternal<Hex20>(
292 candidate, elem, node1, node2, edge_length, info);
293 case HEX27:
294 return findEdgeNeighborsWithinEdgeInternal<Hex27>(
295 candidate, elem, node1, node2, edge_length, info);
296 case TET10:
297 return findEdgeNeighborsWithinEdgeInternal<Tet10>(
298 candidate, elem, node1, node2, edge_length, info);
299 case TET14:
300 return findEdgeNeighborsWithinEdgeInternal<Tet14>(
301 candidate, elem, node1, node2, edge_length, info);
302 case PYRAMID13:
303 return findEdgeNeighborsWithinEdgeInternal<Pyramid13>(
304 candidate, elem, node1, node2, edge_length, info);
305 case PYRAMID14:
306 return findEdgeNeighborsWithinEdgeInternal<Pyramid14>(
307 candidate, elem, node1, node2, edge_length, info);
308 case PRISM15:
309 return findEdgeNeighborsWithinEdgeInternal<Prism15>(
310 candidate, elem, node1, node2, edge_length, info);
311 case PRISM18:
312 return findEdgeNeighborsWithinEdgeInternal<Prism18>(
313 candidate, elem, node1, node2, edge_length, info);
314 default:
315 mooseError("Element type ",
316 Utility::enum_to_string(candidate->type()),
317 " not supported in TraceRayTools::findEdgeNeighbors()");
318 }
319 };
320
321 // Fill info for the element that was passed in
322 within_edge(elem);
323
325 elem, neighbor_set, untested_set, next_untested_set, active_neighbor_children, within_edge);
326}
unsigned int get_node_index(const Node *node_ptr) const
void findNeighbors(const Elem *const elem, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &neighbor_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &untested_set, MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &next_untested_set, std::vector< const Elem * > active_neighbor_children, KeepFunctor &keep_functor)
More generalized form of the find_point_neighbors function in libMesh.
const unsigned int invalid_uint
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ findEdgeNeighborsWithinEdgeInternal()

template<typename T >
bool TraceRayTools::findEdgeNeighborsWithinEdgeInternal ( const Elem *const  candidate,
const Elem *const  elem,
const Node *const  vertex1,
const Node *const  vertex2,
const Real  edge_length,
std::vector< NeighborInfo > &  info 
)

Definition at line 234 of file TraceRayTools.h.

240{
241 // If we have the type already: use it so we can avoid all of the virtual
242 // calls that we would be making on Elem
243 mooseAssert(dynamic_cast<const T *>(candidate), "Incorrect elem type");
244 const T * const T_candidate = static_cast<const T *>(candidate);
245
246 // Local index of our two vertices of interest (if any)
247 auto v1 = T_candidate->get_node_index(vertex1);
248 auto v2 = T_candidate->get_node_index(vertex2);
249 // Whether or not we have said vertices
250 const bool has_v1 = v1 != invalid_uint;
251 const bool has_v2 = v2 != invalid_uint;
252
253 // If the candidate has both vertices, it shares the complete edge
254 if (has_v1 && has_v2)
255 {
256 // Add the sides that contain said edge
257 for (MooseIndex(T::num_edges) e = 0; e < T::num_edges; ++e)
258 if (T_candidate->is_node_on_edge(v1, e) && T_candidate->is_node_on_edge(v2, e))
259 {
260 std::vector<unsigned short> sides(2);
261 sides[0] = T::edge_sides_map[e][0];
262 sides[1] = T::edge_sides_map[e][1];
263 info.emplace_back(candidate, std::move(sides), 0, 1);
264 return true;
265 }
266
267 mooseError("Failed to find a side that the vertices are on");
268 }
269
270 const auto n_vertices = T_candidate->n_vertices();
271
272 // If we only have one of the vertices, we can still be contained within the edge if we have
273 // another vertex that is within the edge
274 if (has_v1 || has_v2)
275 {
276 // Local index of the vertex that the candidate and the target edge have in common
277 const auto common_v = has_v1 ? v1 : v2;
278
279 // See if another vertex that isn't the common node is contained
280 MooseIndex(n_vertices) other_v;
281 for (other_v = 0; other_v < n_vertices; ++other_v)
282 if (other_v != common_v &&
283 isWithinSegment(*vertex1, *vertex2, edge_length, T_candidate->point(other_v)))
284 break;
285
286 // If we have the common vertex and another vertex within the target edge, use the sides
287 // that contain both of those vertices
288 if (other_v != n_vertices)
289 {
290 for (MooseIndex(T::num_edges) e = 0; e < T::num_edges; ++e)
291 if (T_candidate->is_node_on_edge(common_v, e) && T_candidate->is_node_on_edge(other_v, e))
292 {
293 std::vector<unsigned short> sides(2);
294 sides[0] = T::edge_sides_map[e][0];
295 sides[1] = T::edge_sides_map[e][1];
296
297 info.emplace_back(
298 candidate,
299 std::move(sides),
300 has_v1 ? 0 : (T_candidate->point(other_v) - (Point)*vertex1).norm() / edge_length,
301 has_v1 ? (T_candidate->point(other_v) - (Point)*vertex1).norm() / edge_length : 1);
302 return true;
303 }
304 mooseError("Failed to find a side that the vertices are on");
305 }
306 else if (T_candidate->level() < elem->level())
307 {
308 for (MooseIndex(T::num_edges) e = 0; e < T::num_edges; ++e)
309 if (T_candidate->is_node_on_edge(common_v, e) &&
310 isWithinSegment(T_candidate->point(T::edge_nodes_map[e][0]),
311 T_candidate->point(T::edge_nodes_map[e][1]),
312 has_v1 ? *vertex2 : *vertex1))
313 {
314 other_v = T::edge_nodes_map[e][0] == common_v ? T::edge_nodes_map[e][1]
315 : T::edge_nodes_map[e][0];
316 std::vector<unsigned short> sides(2);
317 sides[0] = T::edge_sides_map[e][0];
318 sides[1] = T::edge_sides_map[e][1];
319
320 info.emplace_back(
321 candidate,
322 std::move(sides),
323 has_v1 ? 0 : (T_candidate->point(other_v) - (Point)*vertex1).norm() / edge_length,
324 has_v1 ? (T_candidate->point(other_v) - (Point)*vertex1).norm() / edge_length : 1);
325 return true;
326 }
327
328 return false;
329 }
330 }
331 // When the candidate level is less, one of our vertices could be in a candidate's face and the
332 // other could be within one of the candidate's edges
333 else if (T_candidate->level() < elem->level())
334 {
335 auto v1_edge = RayTracingCommon::invalid_edge;
336 auto v2_edge = RayTracingCommon::invalid_edge;
337
338 // See if any of the edges contain one of the vertices
339 for (MooseIndex(T::num_edges) e = 0; e < T::num_edges; ++e)
340 {
341 if (v1_edge == RayTracingCommon::invalid_edge &&
342 isWithinSegment(T_candidate->point(T::edge_nodes_map[e][0]),
343 T_candidate->point(T::edge_nodes_map[e][1]),
344 *vertex1))
345 v1_edge = e;
346 if (v2_edge == RayTracingCommon::invalid_edge &&
347 isWithinSegment(T_candidate->point(T::edge_nodes_map[e][0]),
348 T_candidate->point(T::edge_nodes_map[e][1]),
349 *vertex2))
350 v2_edge = e;
351 }
352
353 const auto v1_within = v1_edge != RayTracingCommon::invalid_edge;
354 const auto v2_within = v2_edge != RayTracingCommon::invalid_edge;
355
356 if (v1_within && v2_within)
357 {
358 mooseAssert(v1_edge == v2_edge, "Vertices should be contained in same edge");
359
360 std::vector<unsigned short> sides(2);
361 sides[0] = T::edge_sides_map[v1_edge][0];
362 sides[1] = T::edge_sides_map[v1_edge][1];
363 info.emplace_back(candidate, std::move(sides), 0, 1);
364 return true;
365 }
366 else if (v1_within || v2_within)
367 {
368 const auto in_edge = v1_within ? v1_edge : v2_edge;
369 const Point & check_point = v1_within ? *vertex2 : *vertex1;
370
371 std::vector<unsigned short> sides(1);
372 Real lower_bound = 0;
373 Real upper_bound = 1;
374
375 if (candidate->side_ptr(T::edge_sides_map[in_edge][0])->contains_point(check_point))
376 sides[0] = T::edge_sides_map[in_edge][0];
377 else if (candidate->side_ptr(T::edge_sides_map[in_edge][1])->contains_point(check_point))
378 sides[0] = T::edge_sides_map[in_edge][1];
379 else
380 {
381 const Real point_bound = v1_within ? 0 : 1;
382 lower_bound = point_bound;
383 upper_bound = point_bound;
384 sides[0] = T::edge_sides_map[in_edge][0];
385 sides.push_back(T::edge_sides_map[in_edge][1]);
386 }
387
388 info.emplace_back(candidate, std::move(sides), lower_bound, upper_bound);
389 return true;
390 }
391
392 return false;
393 }
394 // If we have neither of the vertices, and the candidate's edge can't fully contain [vertex1,
395 // vertex2], check for other vertices that are contained within the edge
396 else
397 {
398 for (v1 = 0; v1 < n_vertices; ++v1)
399 if (isWithinSegment(*vertex1, *vertex2, edge_length, candidate->point(v1)))
400 {
401 for (v2 = v1 + 1; v2 < n_vertices; ++v2)
402 if (isWithinSegment(*vertex1, *vertex2, edge_length, candidate->point(v2)))
403 break;
404 break;
405 }
406
407 // No vertices are contained within the edge
408 if (v1 == n_vertices)
409 return false;
410
411 // Only one vertex contained: add the sides associated with that vertex
412 if (v2 >= n_vertices)
413 {
414 std::vector<unsigned short> sides;
415 sides.reserve(2);
416
417 for (MooseIndex(T::num_sides) s = 0; s < T::num_sides; ++s)
418 if (T_candidate->is_node_on_side(v1, s))
419 sides.push_back(s);
420
421 if (sides.empty())
422 mooseError("Failed to find sides that the vertex is on");
423
424 // Bounds are the same because we only touch at a point
425 const auto bound = (T_candidate->point(v1) - (Point)*vertex1).norm() / edge_length;
426 info.emplace_back(candidate, std::move(sides), bound, bound);
427 return true;
428 }
429 // Two vertices contained: find the sides that contain both vertices
430 else
431 {
432 for (MooseIndex(T::num_edges) e = 0; e < T::num_edges; ++e)
433 if (T_candidate->is_node_on_edge(v1, e) && T_candidate->is_node_on_edge(v2, e))
434 {
435 auto lower_bound = (T_candidate->point(v1) - (Point)*vertex1).norm() / edge_length;
436 auto upper_bound = (T_candidate->point(v2) - (Point)*vertex1).norm() / edge_length;
437 if (lower_bound > upper_bound)
438 {
439 const auto temp = lower_bound;
440 lower_bound = upper_bound;
441 upper_bound = temp;
442 }
443
444 std::vector<unsigned short> sides(2);
445 sides[0] = T::edge_sides_map[e][0];
446 sides[1] = T::edge_sides_map[e][1];
447 info.emplace_back(candidate, std::move(sides), lower_bound, upper_bound);
448 return true;
449 }
450
451 mooseError("Failed to find sides that the vertices are on");
452 }
453 }
454
455 return false;
456}
const double T
char ** sides
static const unsigned short invalid_edge
Identifier for an invalid edge index.
MPI_Info info
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.
auto norm(const T &a)

◆ findNeighbors()

template<typename KeepFunctor >
void TraceRayTools::findNeighbors ( const Elem *const  elem,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  neighbor_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  untested_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  next_untested_set,
std::vector< const Elem * >  active_neighbor_children,
KeepFunctor &  keep_functor 
)

More generalized form of the find_point_neighbors function in libMesh.

Instead uses a statically allocated set and accepts a functor for the rejection/acceptance of an element.

Returns the active neighbors that fit the criteria of keep_functor. Does not the return the current element (elem)

Parameters
elemThe element for which we are searching for the neighbors
neighbor_setThe set to fill the neighbors into
untested_setSet for internal use
next_untested_setSet for internal use
active_neighbor_childrenVector to use in the search
keep_functorThe functor that is used to accept or reject an element

Definition at line 179 of file TraceRayTools.h.

186{
187 mooseAssert(elem->active(), "Inactive element");
188
189 neighbor_set.clear();
190 untested_set.clear();
191 next_untested_set.clear();
192
193 untested_set.insert(elem);
194
195 while (!untested_set.empty())
196 {
197 // Loop over all the elements in the patch that haven't already been tested
198 for (const Elem * const test_elem : untested_set)
199 for (const auto * const current_neighbor : test_elem->neighbor_ptr_range())
200 if (current_neighbor && current_neighbor != remote_elem &&
201 current_neighbor != elem) // we have a real neighbor on elem side
202 {
203 if (current_neighbor->active()) // ... if it is active
204 {
205 if (!neighbor_set.contains(current_neighbor) && keep_functor(current_neighbor))
206 {
207 next_untested_set.insert(current_neighbor);
208 neighbor_set.insert(current_neighbor);
209 }
210 }
211#ifdef LIBMESH_ENABLE_AMR
212 else // ... the neighbor is *not* active,
213 { // ... so add *all* neighboring
214 // active children that touch p
215 current_neighbor->active_family_tree_by_neighbor(active_neighbor_children, test_elem);
216
217 for (const Elem * current_child : active_neighbor_children)
218 if (!neighbor_set.contains(current_child) && keep_functor(current_child) &&
219 current_child != elem)
220 {
221 next_untested_set.insert(current_child);
222 neighbor_set.insert(current_child);
223 }
224 }
225#endif // #ifdef LIBMESH_ENABLE_AMR
226 }
227 untested_set.swap(next_untested_set);
228 next_untested_set.clear();
229 }
230}
for(PetscInt i=0;i< nvars;++i)
bool contains(const T &value) const
void swap(StaticallyAllocatedSet< T, N > &other)
bool contains(std::string_view superstring, std::string_view substring)
if(subdm)

Referenced by findEdgeNeighbors(), findNodeNeighbors(), and findPointNeighbors().

◆ findNodeNeighbors() [1/2]

void TraceRayTools::findNodeNeighbors ( const Elem *const  elem,
const Node *const  node,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  neighbor_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  untested_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  next_untested_set,
std::vector< const Elem * >  active_neighbor_children,
std::vector< NeighborInfo > &  info 
)

◆ findNodeNeighbors() [2/2]

void TraceRayTools::findNodeNeighbors ( const Elem *const  elem,
const Node *const  node,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  neighbor_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  untested_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  next_untested_set,
std::vector< const Elem * >  active_neighbor_children,
std::vector< NeighborInfo > &  info 
)

Definition at line 179 of file TraceRayTools.C.

187{
188 mooseAssert(elem->get_node_index(node) != libMesh::invalid_uint, "Doesn't contain node");
189
190 info.clear();
191
192 // Helper for avoiding extraneous allocations when building side elements
193 std::unique_ptr<const Elem> side_helper;
194
195 auto contains_node = [&node, &elem, &info, &side_helper](const Elem * const candidate)
196 {
197 // Candidate has this node and it is a vertex - add sides that contain said node
198 const auto n = candidate->get_node_index(node);
199 if (n != invalid_uint && candidate->is_vertex(n))
200 {
201 std::vector<unsigned short> sides;
202 for (const auto s : candidate->side_index_range())
203 if (candidate->is_node_on_side(n, s))
204 sides.push_back(s);
205
206 if (sides.empty())
207 mooseError("Failed to find a side containing node");
208
209 info.emplace_back(candidate, std::move(sides));
210 return true;
211 }
212 // In the case of a less refined candidate, the node can be a hanging node. The candidate
213 // will only ever have the hanging node if it is less refined.
214 if (candidate->level() < elem->level() && candidate->contains_point(*node))
215 {
216 std::vector<unsigned short> sides;
217 for (const auto s : candidate->side_index_range())
218 {
219 candidate->build_side_ptr(side_helper, s);
220 if (side_helper->contains_point(*node))
221 sides.push_back(s);
222 }
223
224 if (!sides.empty())
225 {
226 info.emplace_back(candidate, std::move(sides));
227 return true;
228 }
229 }
230
231 return false;
232 };
233
234 // Fill info for the element that was passed in
235 contains_node(elem);
236
238 elem, neighbor_set, untested_set, next_untested_set, active_neighbor_children, contains_node);
239
240#ifndef NDEBUG
241 // In non-opt modes, verify that we found all of the correct neighbors
242 // using the more expensive libMesh routine
243 std::set<const Elem *> point_neighbors;
244 elem->find_point_neighbors(*node, point_neighbors);
245 for (const auto & point_neighbor : point_neighbors)
246 for (const auto & neighbor_node : point_neighbor->node_ref_range())
247 if (node == &neighbor_node && !neighbor_set.contains(point_neighbor) &&
248 point_neighbor != elem)
249 mooseError("Missed a node neighbor");
250#endif
251}

◆ findPointNeighbors() [1/2]

void TraceRayTools::findPointNeighbors ( const Elem *const  elem,
const Point &  point,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  neighbor_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  untested_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  next_untested_set,
std::vector< const Elem * >  active_neighbor_children,
std::vector< NeighborInfo > &  info 
)

Rewrite of the find_point_neighbors function in libMesh, instead using a statically allocated set: returns the active point neighbors at p within elem.

Parameters
elemThe element
pThe point
neighbor_setThe set to fill the neighbors into
untested_setSet for internal use
next_untested_setSet for internal use
active_neighbor_childrenTemporary vector for use in the search

Referenced by TraceRay::getPointNeighbors(), and TEST().

◆ findPointNeighbors() [2/2]

void TraceRayTools::findPointNeighbors ( const Elem *const  elem,
const Point point,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  neighbor_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  untested_set,
MooseUtils::StaticallyAllocatedSet< const Elem *, MAX_POINT_NEIGHBORS > &  next_untested_set,
std::vector< const Elem * >  active_neighbor_children,
std::vector< NeighborInfo > &  info 
)

Definition at line 118 of file TraceRayTools.C.

126{
127 mooseAssert(elem->contains_point(point), "Doesn't contain point");
128
129 info.clear();
130
131 // Helper for avoiding extraneous allocation when building side elements
132 std::unique_ptr<const Elem> side_helper;
133
134 auto contains_point = [&point, &info, &side_helper, &elem](const Elem * const candidate)
135 {
136 if (candidate->contains_point(point))
137 {
138 std::vector<unsigned short> sides;
139 for (const auto s : candidate->side_index_range())
140 {
141 candidate->build_side_ptr(side_helper, s);
142 if (side_helper->contains_point(point))
143 sides.push_back(s);
144 }
145
146 // Dont add the local element
147 if (!sides.empty() && candidate != elem)
148 {
149 info.emplace_back(candidate, std::move(sides));
150 return true;
151 }
152 }
153
154 return false;
155 };
156
157 // Fill info for the element that was passed in
158 contains_point(elem);
159
160 findNeighbors(elem,
161 neighbor_set,
162 untested_set,
163 next_untested_set,
164 active_neighbor_children,
165 contains_point);
166
167#ifndef NDEBUG
168 // In non-opt modes, verify that we found all of the correct neighbors
169 // using the more expensive libMesh routine
170 std::set<const Elem *> point_neighbors;
171 elem->find_point_neighbors(point, point_neighbors);
172 for (const auto & point_neighbor : point_neighbors)
173 if (!neighbor_set.contains(point_neighbor) && point_neighbor != elem)
174 mooseError("Missed a point neighbor");
175#endif
176}
void find_point_neighbors(const Point &p, std::set< const Elem * > &neighbor_set) const
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const

◆ getActiveNeighbor() [1/2]

const Elem * TraceRayTools::getActiveNeighbor ( const Elem *  elem,
const unsigned short  side,
const Point &  point 
)

Get the active neighbor on side of elem that contains point.

Parameters
elemThe element
sideThe side of elem that point is on
pointThe point on the side you want the neighbor for
Returns
The active neighbor that contains the point

Referenced by TraceRay::trace().

◆ getActiveNeighbor() [2/2]

const Elem * TraceRayTools::getActiveNeighbor ( const Elem elem,
const unsigned short  side,
const Point point 
)

Definition at line 355 of file TraceRayTools.C.

356{
357 const auto neighbor = elem->neighbor_ptr(side);
358 if (!neighbor || neighbor->active())
359 return neighbor;
360
361 // There is adaptivity... need to find the active child that contains the point
362 const auto neighbor_side = neighbor->which_neighbor_am_i(elem);
363 return childContainingPointOnSide(neighbor, point, neighbor_side);
364}
unsigned int which_neighbor_am_i(const Elem *e) const
const Elem * neighbor_ptr(unsigned int i) const

◆ intersectQuad() [1/2]

bool TraceRayTools::intersectQuad ( const Point &  start,
const Point &  direction,
const Elem *const  elem,
const unsigned short  v00,
const unsigned short  v10,
const unsigned short  v11,
const unsigned short  v01,
Real &  intersection_distance,
ElemExtrema intersected_extrema,
const Real hmax #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

Checks for the intersection of a ray and a quadrilateral, numbered as such:

v01 v11 o-----—o | | | | o-----—o v00 v10

Uses intersectTriangle() to check the possible intersection with the two triangles that make up the quad

Parameters
startStart point of the ray
directionDirection of the ray
elemThe elem that contains the quad face (used to get the vertex points)
v00Vertex index on elem that represents v00 in the method description
v10Vertex index on elem that represents v10 in the method description
v11Vertex index on elem that represents v11 in the method description
v01Vertex index on elem that represents v01 in the method description
intersection_distanceIf intersected, storage for the intersection distance
intersected_extremaIf a vertex/edge is intersected, will be filled with the intersection
Returns
Whether or not the ray intersected the quadrilateral

Referenced by sideIntersectedByLine().

◆ intersectQuad() [2/2]

bool TraceRayTools::intersectQuad ( const Point start,
const Point direction,
const Elem *const  elem,
const unsigned short  v00,
const unsigned short  v10,
const unsigned short  v11,
const unsigned short  v01,
Real &  intersection_distance,
ElemExtrema intersected_extrema,
const Real hmax #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

Definition at line 476 of file TraceRayTools.C.

491{
492 mooseAssert(intersected_extrema.isInvalid(), "Should be invalid");
493 debugRaySimple("intersectQuad() called:");
494 debugRaySimple(" start = ", start);
495 debugRaySimple(" direction = ", direction);
496 debugRaySimple(" elem->id() = ", elem->id());
497 debugRaySimple(" v00 = ", v00, " at ", elem->point(v00));
498 debugRaySimple(" v10 = ", v10, " at ", elem->point(v10));
499 debugRaySimple(" v11 = ", v11, " at ", elem->point(v11));
500 debugRaySimple(" v01 = ", v01, " at ", elem->point(v01));
501
502 // NOTE discovered by @GiudGiud: In the case that you have
503 // a glancing intersection (the direction is within the plane
504 // of the face), you could possibly miss a further intersection
505 // on the second triangle. In reality, this should not be
506 // a problem because we check all sides of the element, so
507 // we would find a further intersection in the future.
508
509 // First check the triangle contained by v00, v10, v11
510 bool intersects = intersectTriangle(start,
511 direction,
512 elem,
513 v00,
514 v10,
515 v11,
516 intersection_distance,
517 intersected_extrema,
518 hmax
519#ifdef DEBUG_RAY_INTERSECTIONS
520 ,
521 debug
522#endif
523 );
524 // If no intersection, check the triangle contained by v11, v01, v00
525 if (!intersects)
526 intersects = intersectTriangle(start,
527 direction,
528 elem,
529 v11,
530 v01,
531 v00,
532 intersection_distance,
533 intersected_extrema,
534 hmax
535#ifdef DEBUG_RAY_INTERSECTIONS
536 ,
537 debug
538#endif
539 );
540
541 // Because we split the quad into two triangles, we could intersect the edge v00 - v11. However,
542 // that really isn't an edge - it's a diagonal across the quad. If we intersect this edge, be sure
543 // to invalidate it
544 if (intersects && intersected_extrema.atEdge(v00, v11))
545 intersected_extrema.invalidate();
546
547 return intersects;
548}
dof_id_type id() const
bool intersectTriangle(const Point &start, const Point &direction, const Elem *const elem, const unsigned short v0, const unsigned short v1, const unsigned short v2, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
Checks for the intersection of a ray and a triangular face.
bool isInvalid() const
Definition ElemExtrema.h:48
bool atEdge() const
Definition ElemExtrema.h:71
void invalidate()
Invalidates the current state.
Definition ElemExtrema.h:87

◆ intersectTriangle() [1/2]

bool TraceRayTools::intersectTriangle ( const Point &  start,
const Point &  direction,
const Elem *const  elem,
const unsigned short  v0,
const unsigned short  v1,
const unsigned short  v2,
Real &  intersection_distance,
ElemExtrema intersected_extrema,
const Real hmax #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

Checks for the intersection of a ray and a triangular face.

Adapted from: webserver2.tecgraf.puc-rio.br/~mgattass/cg/trbRR/Fast%20MinimumStorage%20RayTriangle%20Intersection.pdf

Parameters
startStart point of the ray
directionDirection of the ray
elemThe elem that contains the triangular face (used to get the vertex points)
v0Vertex index on elem that is the zeroth vertex of the triangular face
v1Vertex index on elem that is the first vertex of the triangular face
v2Vertex index on elem that is the second vertex of the triangular face
intersection_distanceIf intersected, storage for the intersection distance
intersected_extremaIf a vertex/edge is intersected, will be filled with the intersection
Returns
Whether or not the ray intersected the triangular face

Referenced by intersectQuad(), and sideIntersectedByLine().

◆ intersectTriangle() [2/2]

bool TraceRayTools::intersectTriangle ( const Point start,
const Point direction,
const Elem *const  elem,
const unsigned short  v0,
const unsigned short  v1,
const unsigned short  v2,
Real &  intersection_distance,
ElemExtrema intersected_extrema,
const Real hmax #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

Definition at line 367 of file TraceRayTools.C.

381{
382 debugRaySimple("intersectTriangle() called:");
383 debugRaySimple(" start = ", start);
384 debugRaySimple(" direction = ", direction);
385 debugRaySimple(" elem->id() = ", elem->id());
386 debugRaySimple(" v0 = ", v0, " at ", elem->point(v0));
387 debugRaySimple(" v1 = ", v1, " at ", elem->point(v1));
388 debugRaySimple(" v2 = ", v2, " at ", elem->point(v2));
389 debugRaySimple(" hmax = ", hmax);
390 mooseAssert(elem->is_vertex(v0), "Not a vertex");
391 mooseAssert(elem->is_vertex(v1), "Not a vertex");
392 mooseAssert(elem->is_vertex(v2), "Not a vertex");
393
394 // We are scaling the whole element (start, v0, v1, v2) by 1 / hmax as an alternative to scaling
395 // the tolerance by hmax. If an intersection is found, the resulting intersection distance is
396 // then scaled by hmax to reverse the original scaling.
397 const auto inv_hmax = 1.0 / hmax;
398
399 const auto & v0_point = elem->point(v0);
400
401 const auto edge1 = (elem->point(v1) - v0_point) * inv_hmax;
402 const auto edge2 = (elem->point(v2) - v0_point) * inv_hmax;
403
404 const auto pvec = direction.cross(edge2);
405
406 auto det = edge1 * pvec;
407 debugRaySimple(" det = ", det);
408 if (det < TRACE_TOLERANCE)
409 {
410 debugRaySimple("intersectTriangle() did not intersect: det < tol");
411 return false;
412 }
413
414 const auto tvec = (start - v0_point) * inv_hmax;
415 const auto u = tvec * pvec;
416 debugRaySimple(" u = ", u);
417 debugRaySimple(" u / det = ", u / det);
418 if (u < -TRACE_TOLERANCE || u > det + TRACE_TOLERANCE)
419 {
420 debugRaySimple("intersectTriangle() did not intersect: u out of range");
421 return false;
422 }
423
424 const auto qvec = tvec.cross(edge1);
425 const auto v = direction * qvec;
426 debugRaySimple(" v = ", v);
427 debugRaySimple(" v / det = ", v / det);
428 debugRaySimple(" (u + v) / det = ", (u + v) / det);
429 if (v < -TRACE_TOLERANCE || u + v > det + TRACE_TOLERANCE)
430 {
431 debugRaySimple("intersectTriangle() did not intersect: v out of range");
432 return false;
433 }
434
435 const auto possible_distance = (edge2 * qvec) / det;
436 debugRaySimple(" possible_distance = ", possible_distance);
437 if (possible_distance <= TRACE_TOLERANCE)
438 {
439 debugRaySimple("intersectTriangle() did not intersect: distance too small");
440 return false;
441 }
442
443 // Recall that the element was scaled by (1 / hmax), reverse this scaling by
444 // scaling the intersection distance by hmax
445 intersection_distance = possible_distance * hmax;
446
447 // Here, u and v aren't truly u and v. The actual u and v are obtained with:
448 // u = u / det and v = v / det -> move det to the RHS to avoid division
449 if (u < TRACE_TOLERANCE * det)
450 {
451 if (v < TRACE_TOLERANCE * det) // u = 0, v = 0
452 intersected_extrema.setVertex(v0);
453 else if (v > (1.0 - TRACE_TOLERANCE) * det) // u = 0, v = 1
454 intersected_extrema.setVertex(v2);
455 else // u = 0
456 intersected_extrema.setEdge(v0, v2);
457 }
458 else if (v < TRACE_TOLERANCE * det)
459 {
460 if (u > (1.0 - TRACE_TOLERANCE) * det) // u = 1, v = 0
461 intersected_extrema.setVertex(v1);
462 else // v = 0
463 intersected_extrema.setEdge(v0, v1);
464 }
465 else if ((u + v > (1.0 - TRACE_TOLERANCE) * det)) // u + v = 1
466 intersected_extrema.setEdge(v1, v2);
467
468 debugRaySimple("intersectTriangle() intersected with:");
469 debugRaySimple(" intersection_distance = ", intersection_distance);
470 debugRaySimple(" intersected_extrema = ", intersected_extrema);
471
472 return true;
473}
virtual bool is_vertex(const unsigned int i) const=0
TypeVector< typename CompareTypes< Real, T2 >::supertype > cross(const TypeVector< T2 > &v) const
void setVertex(const unsigned short vertex)
Sets the "at vertex" state.
void setEdge(const unsigned short v1, const unsigned short v2)
Sets the "at edge" state.

◆ isAdaptivityTraceableElem() [1/2]

bool TraceRayTools::isAdaptivityTraceableElem ( const Elem *  elem)
Returns
Whether or not the element is traceable with adaptivity

Referenced by RayTracingStudy::traceableMeshChecks().

◆ isAdaptivityTraceableElem() [2/2]

bool TraceRayTools::isAdaptivityTraceableElem ( const Elem elem)

Definition at line 557 of file TraceRayTools.C.

558{
559 return ADAPTIVITY_TRACEABLE_ELEMTYPES.count(elem->type());
560}
const std::set< int > ADAPTIVITY_TRACEABLE_ELEMTYPES
The element types that are traceable with adaptivity.

◆ isTraceableElem() [1/2]

bool TraceRayTools::isTraceableElem ( const Elem *  elem)
Returns
Whether not the element is traceable

Referenced by RayTracingStudy::traceableMeshChecks().

◆ isTraceableElem() [2/2]

bool TraceRayTools::isTraceableElem ( const Elem elem)

Definition at line 551 of file TraceRayTools.C.

552{
553 return TRACEABLE_ELEMTYPES.count(elem->type());
554}
const std::set< int > TRACEABLE_ELEMTYPES
The element types that are traceable.

◆ isWithinSegment() [1/4]

bool TraceRayTools::isWithinSegment ( const Point segment1,
const Point segment2,
const Point point,
const Real  tolerance 
)

Definition at line 779 of file TraceRayTools.C.

783{
784 mooseAssert(!segment1.absolute_fuzzy_equals(segment2, TRACE_TOLERANCE), "Same endpoints");
785
786 const auto segment_length = (segment1 - segment2).norm();
787 return isWithinSegment(segment1, segment2, segment_length, point, tolerance);
788}

◆ isWithinSegment() [2/4]

bool TraceRayTools::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.

Parameters
segment1The first point on the segment
segment2The second point on the segment
pointThe point
toleranceThe tolerance to use
Returns
If point is within the segment defined by [segment1, segment2]

Referenced by findEdgeNeighborsWithinEdgeInternal(), TraceRay::getEdgeNeighbors(), BoundingBoxIntersectionHelper::intersection(), isWithinSegment(), TEST(), withinEdgeOnSideTempl(), and withinEdgeTempl().

◆ isWithinSegment() [3/4]

bool TraceRayTools::isWithinSegment ( const Point segment1,
const Point segment2,
const Real  segment_length,
const Point point,
const Real  tolerance 
)

Definition at line 791 of file TraceRayTools.C.

796{
797 mooseAssert(!segment1.absolute_fuzzy_equals(segment2, TRACE_TOLERANCE), "Same endpoints");
798 mooseAssert(MooseUtils::absoluteFuzzyEqual((segment1 - segment2).norm(), segment_length),
799 "Invalid segment length");
800
801 const auto diff1 = point - segment1;
802 const auto diff2 = point - segment2;
803
804 if (diff1 * diff2 > tolerance * segment_length)
805 return false;
806
807 return std::abs(diff1.norm() + diff2.norm() - segment_length) < tolerance * segment_length;
808}

◆ isWithinSegment() [4/4]

bool TraceRayTools::isWithinSegment ( const Point &  segment1,
const Point &  segment2,
const Real  segment_length,
const Point &  point,
const Real  tolerance = TRACE_TOLERANCE 
)

Checks whether or not a point is within a line segment.

Parameters
segment1The first point on the segment
segment2The second point on the segment
segment_lengthThe segment length (for optimization if it's already computed)
pointThe point
toleranceThe tolerance to use
Returns
If point is within the segment defined by [segment1, segment2]

◆ lineLineIntersect2D() [1/2]

bool TraceRayTools::lineLineIntersect2D ( const Point &  start,
const Point &  direction,
const Real  length,
const Point &  v0,
const Point &  v1,
Point &  intersection_point,
Real &  intersection_distance,
SegmentVertices &segment_vertex #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

Checks for the intersection of the line u0 -> u1 with the line v0 -> v1, where u0 = start and u1 = start + direction * length.

From: https://stackoverflow.com/a/565282

Returns
Whether or not the lines intersect
Parameters
startThe start point, u0
directionThe direction used to define u1
lengthThe length used to define u1
v0The point v0
v1The point v1
intersection_pointTo be filled with the point of intersection
intersection_distanceTo be filled with the distance of intersection
segment_vertexTo be filled with the intersected vertex, if any

Referenced by sideIntersectedByLine().

◆ lineLineIntersect2D() [2/2]

bool TraceRayTools::lineLineIntersect2D ( const Point start,
const Point direction,
const Real  length,
const Point v0,
const Point v1,
Point intersection_point,
Real &  intersection_distance,
SegmentVertices &segment_vertex #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

Definition at line 48 of file TraceRayTools.C.

62{
63 // TODO: consider using hmax scaling here
64 mooseAssert(segment_vertex == SEGMENT_VERTEX_NONE, "Vertex should be none");
65 debugRaySimple("Called lineLineIntersect2D()");
66 debugRaySimple(" start = ", start);
67 debugRaySimple(" direction = ", direction);
68 debugRaySimple(" length = ", length);
69 debugRaySimple(" v0 = ", v0);
70 debugRaySimple(" v1 = ", v1);
71
72 const auto r = direction * length;
73 const auto s = v1 - v0;
74
75 const auto rxs = r(0) * s(1) - r(1) * s(0);
76 debugRaySimple(" rxs = ", rxs);
77
78 // Lines are parallel or colinear
79 if (std::abs(rxs) < TRACE_TOLERANCE)
80 return false;
81
82 const auto v0mu0 = v0 - start;
83
84 const auto t = (v0mu0(0) * s(1) - v0mu0(1) * s(0)) / rxs;
85 debugRaySimple(" t = ", t);
86 if (0 >= t + TRACE_TOLERANCE || t - TRACE_TOLERANCE > 1.0)
87 {
88 debugRaySimple("lineLineIntersect2D did not intersect: t out of range");
89 return false;
90 }
91
92 const auto u = (v0mu0(0) * r(1) - v0mu0(1) * r(0)) / rxs;
93 debugRaySimple(" u = ", u);
94 if (0 < u + TRACE_TOLERANCE && u - TRACE_TOLERANCE <= 1.0)
95 {
96 intersection_point = start + r * t;
97 intersection_distance = t * length;
98
99 if (u < TRACE_TOLERANCE)
100 segment_vertex = SEGMENT_VERTEX_0;
101 else if (u > 1.0 - TRACE_TOLERANCE)
102 segment_vertex = SEGMENT_VERTEX_1;
103
104 debugRaySimple("lineLineIntersect2D intersected with:");
105 debugRaySimple(" intersection_distance = ", intersection_point);
106 debugRaySimple(" intersection_distance = ", intersection_distance);
107 debugRaySimple(" segment_vertex = ", Utility::enum_to_string(segment_vertex));
108
109 return true;
110 }
111
112 // Not parallel, but don't intersect
113 debugRaySimple("lineLineIntersect2d() did not intersect: u out of range");
114 return false;
115}

◆ nodesPerSide() [1/3]

template<typename T >
std::enable_if< std::is_base_of< Pyramid, T >::value, unsignedshort >::type TraceRayTools::nodesPerSide ( const unsigned short  side)
inline

Returns the number of nodes on a side on a Pyramid elem.

Definition at line 907 of file TraceRayTools.h.

908{
909 return T::nodes_per_side - (side != 4);
910}

◆ nodesPerSide() [2/3]

template<typename T >
std::enable_if< std::is_base_of< libMesh::Prism, T >::value, unsignedshort >::type TraceRayTools::nodesPerSide ( const unsigned short  side)
inline

Returns the number of nodes on a side on a Prism elem.

Definition at line 917 of file TraceRayTools.h.

918{
919 return T::nodes_per_side - (side == 0 || side == 4);
920}

◆ nodesPerSide() [3/3]

template<typename T >
std::enable_if<!std::is_base_of< libMesh::Pyramid, T >::value &&!std::is_base_of< libMesh::Prism, T >::value, unsignedshort >::type TraceRayTools::nodesPerSide ( const unsigned short  )
inline

Returns the number of nodes on a side for an Elem that is not a Pyramid or Prism.

Definition at line 897 of file TraceRayTools.h.

898{
899 return T::nodes_per_side;
900}

◆ onBoundingBoxBoundary() [1/2]

bool TraceRayTools::onBoundingBoxBoundary ( const BoundingBox &  bbox,
const Point &  point,
const unsigned int  dim,
const Real  tolerance 
)

Whether or not point is on the boundary (min/max) of bbox.

Checks dim dimensions.

Referenced by TraceRay::trace().

◆ onBoundingBoxBoundary() [2/2]

bool TraceRayTools::onBoundingBoxBoundary ( const BoundingBox bbox,
const Point point,
const unsigned int  dim,
const Real  tolerance 
)

Definition at line 811 of file TraceRayTools.C.

815{
816 for (unsigned int d = 0; d < dim; ++d)
817 if (MooseUtils::absoluteFuzzyEqual(point(d), bbox.min()(d), tolerance) ||
818 MooseUtils::absoluteFuzzyEqual(point(d), bbox.max()(d), tolerance))
819 return true;
820
821 return false;
822}
unsigned int dim
const Point & max() const
const Point & min() const

◆ sideIntersectedByLine() [1/5]

template<typename T >
std::enable_if< std::is_base_of< libMesh::Face, T >::value, bool >::type TraceRayTools::sideIntersectedByLine ( const Elem *  elem,
const Point &  start_point,
const Point &  direction,
const unsigned short  side,
const Real  max_length,
Point &  intersection_point,
Real &  intersection_distance,
ElemExtrema intersected_extrema,
const Real #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

SFINAE typed object for checking the intersection of a line segment with the face of a Face typed element, i.e., the intersection with the edge of a 2D element.

Parameters
elemThe element to check
start_pointStart point of the segment
directionDirection of the segment
sideThe side of elem to check
max_lengthA length that is longer than the length of the line segment
intersection_pointIf intersected, storage for the intersection point
intersection_distanceIf intersected, storage for the intersection distance
intersected_extremaIf a vertex/edge is intersected, will be filled with the intersection
Returns
Whether or not the line segment intersected with the face

Definition at line 564 of file TraceRayTools.h.

578{
579 mooseAssert(intersection_point == RayTracingCommon::invalid_point, "Point should be invalid");
580 mooseAssert(intersected_extrema.isInvalid(), "Should be invalid");
581
582 SegmentVertices segment_vertex = SEGMENT_VERTEX_NONE;
583
584 const bool intersected = lineLineIntersect2D(start_point,
585 direction,
586 max_length,
587 elem->point(T::side_nodes_map[side][0]),
588 elem->point(T::side_nodes_map[side][1]),
589 intersection_point,
590 intersection_distance,
591 segment_vertex
592#ifdef DEBUG_RAY_INTERSECTIONS
593 ,
594 debug
595#endif
596 );
597
598 if (segment_vertex != SEGMENT_VERTEX_NONE)
599 {
600 intersected_extrema.setVertex(T::side_nodes_map[side][segment_vertex]);
601 mooseAssert(
602 intersected_extrema.vertexPoint(elem).absolute_fuzzy_equals(intersection_point,
603 3 * TRACE_TOLERANCE),
604 "Doesn't intersect vertex at: " + Moose::stringify(intersected_extrema.vertexPoint(elem)) +
605 " tentative intersection point: " + Moose::stringify(intersection_point));
606 }
607
608 return intersected;
609}
std::string stringify(const T &t)
static const libMesh::Point invalid_point(invalid_distance, invalid_distance, invalid_distance)
Identifier for an invalid point.
bool lineLineIntersect2D(const Point &start, const Point &direction, const Real length, const Point &v0, const Point &v1, Point &intersection_point, Real &intersection_distance, SegmentVertices &segment_vertex #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
Checks for the intersection of the line u0 -> u1 with the line v0 -> v1, where u0 = start and u1 = st...
SegmentVertices
Enum for the possible vertices on a segment used in lineLineIntersect2D()
const Point & vertexPoint(const libMesh::Elem *elem) const
Definition ElemExtrema.C:16

◆ sideIntersectedByLine() [2/5]

template<typename T >
std::enable_if< std::is_base_of< Hex, T >::value, bool >::type TraceRayTools::sideIntersectedByLine ( const Elem *  elem,
const Point &  start_point,
const Point &  direction,
const unsigned short  side,
const Real  ,
Point &  intersection_point,
Real &  intersection_distance,
ElemExtrema intersected_extrema,
const Real hmax #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

SFINAE typed object for checking the intersection of a line segment with the face of a Hex typed element.

Parameters
elemThe element to check
start_pointStart point of the segment
directionDirection of the segment
sideThe side of elem to check
intersection_pointIf intersected, storage for the intersection point
intersection_distanceIf intersected, storage for the intersection distance
intersected_extremaIf a vertex/edge is intersected, will be filled with the intersection
Returns
Whether or not the line segment intersected with the face

Definition at line 625 of file TraceRayTools.h.

639{
640 mooseAssert(elem->first_order_equivalent_type(elem->type()) == HEX8, "Not a Hex");
641 mooseAssert(intersection_point == RayTracingCommon::invalid_point, "Point should be invalid");
642 mooseAssert(intersected_extrema.isInvalid(), "Should be invalid");
643
644 const bool intersected = intersectQuad(start_point,
645 direction,
646 elem,
647 T::side_nodes_map[side][3],
648 T::side_nodes_map[side][2],
649 T::side_nodes_map[side][1],
650 T::side_nodes_map[side][0],
651 intersection_distance,
652 intersected_extrema,
653 hmax
654#ifdef DEBUG_RAY_INTERSECTIONS
655 ,
656 debug
657#endif
658 );
659
660 if (intersected)
661 intersection_point = start_point + intersection_distance * direction;
662
663 return intersected;
664}
bool intersectQuad(const Point &start, const Point &direction, const Elem *const elem, const unsigned short v00, const unsigned short v10, const unsigned short v11, const unsigned short v01, Real &intersection_distance, ElemExtrema &intersected_extrema, const Real hmax #ifdef DEBUG_RAY_INTERSECTIONS, const bool debug #endif)
Checks for the intersection of a ray and a quadrilateral, numbered as such:

◆ sideIntersectedByLine() [3/5]

template<typename T >
std::enable_if< std::is_base_of< Tet, T >::value, bool >::type TraceRayTools::sideIntersectedByLine ( const Elem *  elem,
const Point &  start_point,
const Point &  direction,
const unsigned short  side,
const Real  ,
Point &  intersection_point,
Real &  intersection_distance,
ElemExtrema intersected_extrema,
const Real hmax #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

SFINAE typed object for checking the intersection of a line segment with the face of a Tet typed element.

Parameters
elemThe element to check
start_pointStart point of the segment
directionDirection of the segment
sideThe side of elem to check
max_lengthA length that is longer than the length of the line segment
intersection_pointIf intersected, storage for the intersection point
intersection_distanceIf intersected, storage for the intersection distance
intersected_vertexIf a vertex is intersected, storage for said intersection
intersected_extremaIf a vertex/edge is intersected, will be filled with the intersection
Returns
Whether or not the line segment intersected with the face

Definition at line 682 of file TraceRayTools.h.

696{
697 mooseAssert(elem->first_order_equivalent_type(elem->type()) == TET4, "Not a Tet");
698 mooseAssert(intersection_point == RayTracingCommon::invalid_point, "Point should be invalid");
699 mooseAssert(intersected_extrema.isInvalid(), "Should be invalid");
700
701 const bool intersected = intersectTriangle(start_point,
702 direction,
703 elem,
704 T::side_nodes_map[side][2],
705 T::side_nodes_map[side][1],
706 T::side_nodes_map[side][0],
707 intersection_distance,
708 intersected_extrema,
709 hmax
710#ifdef DEBUG_RAY_INTERSECTIONS
711 ,
712 debug
713#endif
714 );
715
716 if (intersected)
717 intersection_point = start_point + intersection_distance * direction;
718
719 return intersected;
720}

◆ sideIntersectedByLine() [4/5]

template<typename T >
std::enable_if< std::is_base_of< libMesh::Pyramid, T >::value, bool >::type TraceRayTools::sideIntersectedByLine ( const Elem *  elem,
const Point &  start_point,
const Point &  direction,
const unsigned short  side,
const Real  ,
Point &  intersection_point,
Real &  intersection_distance,
ElemExtrema intersected_extrema,
const Real hmax #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

SFINAE typed object for checking the intersection of a line segment with the face of a Pyramid typed element.

Parameters
elemThe element to check
start_pointStart point of the segment
directionDirection of the segment
sideThe side of elem to check
max_lengthA length that is longer than the length of the line segment
intersection_pointIf intersected, storage for the intersection point
intersection_distanceIf intersected, storage for the intersection distance
intersected_vertexIf a vertex is intersected, storage for said intersection
intersected_extremaIf a vertex/edge is intersected, will be filled with the intersection
Returns
Whether or not the line segment intersected with the face

Definition at line 738 of file TraceRayTools.h.

752{
753 mooseAssert(elem->first_order_equivalent_type(elem->type()) == PYRAMID5, "Not a Pyramid");
754 mooseAssert(intersection_point == RayTracingCommon::invalid_point, "Point should be invalid");
755 mooseAssert(intersected_extrema.isInvalid(), "Should be invalid");
756
757 const bool intersected = side < 4 ? intersectTriangle(start_point,
758 direction,
759 elem,
760 T::side_nodes_map[side][2],
761 T::side_nodes_map[side][1],
762 T::side_nodes_map[side][0],
763 intersection_distance,
764 intersected_extrema,
765 hmax
766#ifdef DEBUG_RAY_INTERSECTIONS
767 ,
768 debug
769#endif
770 )
771 : intersectQuad(start_point,
772 direction,
773 elem,
774 T::side_nodes_map[side][3],
775 T::side_nodes_map[side][2],
776 T::side_nodes_map[side][1],
777 T::side_nodes_map[side][0],
778 intersection_distance,
779 intersected_extrema,
780 hmax
781#ifdef DEBUG_RAY_INTERSECTIONS
782 ,
783 debug
784#endif
785 );
786
787 if (intersected)
788 intersection_point = start_point + intersection_distance * direction;
789
790 return intersected;
791}

◆ sideIntersectedByLine() [5/5]

template<typename T >
std::enable_if< std::is_base_of< libMesh::Prism, T >::value, bool >::type TraceRayTools::sideIntersectedByLine ( const Elem *  elem,
const Point &  start_point,
const Point &  direction,
const unsigned short  side,
const Real  ,
Point &  intersection_point,
Real &  intersection_distance,
ElemExtrema intersected_extrema,
const Real hmax #ifdef  DEBUG_RAY_INTERSECTIONS,
const bool debug #  endif 
)

SFINAE typed object for checking the intersection of a line segment with the face of a Prism typed element.

Parameters
elemThe element to check
start_pointStart point of the segment
directionDirection of the segment
sideThe side of elem to check
max_lengthA length that is longer than the length of the line segment
intersection_pointIf intersected, storage for the intersection point
intersection_distanceIf intersected, storage for the intersection distance
intersected_vertexIf a vertex is intersected, storage for said intersection
intersected_extremaIf a vertex/edge is intersected, will be filled with the intersection
Returns
Whether or not the line segment intersected with the face

Definition at line 809 of file TraceRayTools.h.

823{
824 mooseAssert(elem->first_order_equivalent_type(elem->type()) == PRISM6, "Not a Prism");
825 mooseAssert(intersection_point == RayTracingCommon::invalid_point, "Point should be invalid");
826 mooseAssert(intersected_extrema.isInvalid(), "Should be invalid");
827
828 const bool intersected = (side == 0 || side == 4) ? intersectTriangle(start_point,
829 direction,
830 elem,
831 T::side_nodes_map[side][2],
832 T::side_nodes_map[side][1],
833 T::side_nodes_map[side][0],
834 intersection_distance,
835 intersected_extrema,
836 hmax
837#ifdef DEBUG_RAY_INTERSECTIONS
838 ,
839 debug
840#endif
841 )
842 : intersectQuad(start_point,
843 direction,
844 elem,
845 T::side_nodes_map[side][3],
846 T::side_nodes_map[side][2],
847 T::side_nodes_map[side][1],
848 T::side_nodes_map[side][0],
849 intersection_distance,
850 intersected_extrema,
851 hmax
852#ifdef DEBUG_RAY_INTERSECTIONS
853 ,
854 debug
855#endif
856 );
857
858 if (intersected)
859 intersection_point = start_point + intersection_distance * direction;
860
861 return intersected;
862}

◆ withinEdge() [1/2]

bool TraceRayTools::withinEdge ( const Elem elem,
const Point point,
ElemExtrema extrema,
const Real  tolerance 
)

Definition at line 595 of file TraceRayTools.C.

599{
600 switch (elem->type())
601 {
602 case HEX8:
603 case HEX20:
604 case HEX27:
605 return withinEdgeTempl<Hex8>(elem, point, extrema, tolerance);
606 case TET4:
607 case TET10:
608 case TET14:
609 return withinEdgeTempl<Tet4>(elem, point, extrema, tolerance);
610 case PYRAMID5:
611 case PYRAMID13:
612 case PYRAMID14:
613 return withinEdgeTempl<Pyramid5>(elem, point, extrema, tolerance);
614 case PRISM6:
615 case PRISM15:
616 case PRISM18:
617 return withinEdgeTempl<Prism6>(elem, point, extrema, tolerance);
618 default:
619 mooseError("Element type ",
621 " not supported in TraceRayTools::withinEdge()");
622 }
623
624 return false;
625}

◆ withinEdge() [2/2]

bool TraceRayTools::withinEdge ( const Elem *  elem,
const Point &  point,
ElemExtrema extrema,
const Real  tolerance = TRACE_TOLERANCE 
)

Determines if a point is within an edge on an element.

Parameters
elemThe element
pointThe point
extremaTo be filled with the local vertex IDs that contain the edge the point is within, if any
toleranceThe tolerance to use
Returns
If the point is within an edge of the element

Referenced by TEST(), TEST(), and TraceRay::trace().

◆ withinEdgeOnSide() [1/2]

bool TraceRayTools::withinEdgeOnSide ( const Elem *const  elem,
const Point &  point,
const unsigned short  side,
ElemExtrema extrema 
)

Determines if a point is within an edge on the side of an element.

Parameters
elemThe element
pointThe point
sideThe side
extremaTo be filled with the local vertex IDs that contain the edge the point is within, if any
Returns
If the point is within an edge on the side of the element

Referenced by TEST(), TraceRay::trace(), and withinExtremaOnSide().

◆ withinEdgeOnSide() [2/2]

bool TraceRayTools::withinEdgeOnSide ( const Elem *const  elem,
const Point point,
const unsigned short  side,
ElemExtrema extrema 
)

Definition at line 699 of file TraceRayTools.C.

703{
704 switch (elem->type())
705 {
706 case HEX8:
707 case HEX20:
708 case HEX27:
709 return withinEdgeOnSideTempl<Hex8>(elem, point, side, extrema);
710 case TET4:
711 case TET10:
712 case TET14:
713 return withinEdgeOnSideTempl<Tet4>(elem, point, side, extrema);
714 case PYRAMID5:
715 case PYRAMID13:
716 case PYRAMID14:
717 return withinEdgeOnSideTempl<Pyramid5>(elem, point, side, extrema);
718 case PRISM6:
719 case PRISM15:
720 case PRISM18:
721 return withinEdgeOnSideTempl<Prism6>(elem, point, side, extrema);
722 default:
723 mooseError("Element type ",
725 " not supported in TraceRayTools::withinEdgeOnSide()");
726 }
727
728 return false;
729}

◆ withinEdgeOnSideTempl() [1/3]

template<typename T >
std::enable_if< std::is_base_of< libMesh::Cell, T >::value, bool >::type TraceRayTools::withinEdgeOnSideTempl ( const Elem * const  elem,
const Point &  point,
const unsigned short  side,
ElemExtrema extrema 
)

Determines if a point is within an edge on the side of an element.

SFINAE here makes this method available for only 3D elem types (Cell)

The template argument should be the first order type of the elem - this is used to access the vertex mappings for said element without calling any virtuals

Parameters
elemThe element
pointThe point
sideThe side
extremaTo be filled with the local vertex IDs that contain the edge the point is within, if any
Returns
If the point is within an edge on the side of the element

SFINAE here makes this method available for only 1D/2D elem types (not Cell), which do not have edges, therefore this function errors.

Definition at line 1045 of file TraceRayTools.h.

1046{
1047 mooseError("Should not call withinEdgeOnSideTempl() with a non-Cell derived Elem");
1048}

◆ withinEdgeOnSideTempl() [2/3]

template<typename T >
std::enable_if< std::is_base_of< Cell, T >::value, bool >::type TraceRayTools::withinEdgeOnSideTempl ( const Elem *const  elem,
const Point point,
const unsigned short  side,
ElemExtrema extrema 
)

Definition at line 733 of file TraceRayTools.C.

737{
738 mooseAssert(side < elem->n_sides(), "Invalid side");
739 mooseAssert(elem->side_ptr(side)->close_to_point(point, LOOSE_TRACE_TOLERANCE),
740 "Side does not contain point");
741 mooseAssert(extrema.isInvalid(), "Should be invalid");
742
743 int last_n = T::side_nodes_map[side][nodesPerSide<T>(side) - 1];
744
745 for (int side_v = 0; side_v < nodesPerSide<T>(side); ++side_v)
746 if (isWithinSegment(elem->point(last_n), elem->point(T::side_nodes_map[side][side_v]), point))
747 {
748 extrema.setEdge(last_n, T::side_nodes_map[side][side_v]);
749 mooseAssert(extrema.buildEdge(elem)->close_to_point(point, LOOSE_TRACE_TOLERANCE),
750 "Edge doesn't contain point");
751 return true;
752 }
753 else
754 last_n = T::side_nodes_map[side][side_v];
755
756 return false;
757}
std::unique_ptr< const libMesh::Elem > buildEdge(const Elem *elem) const
Definition ElemExtrema.C:22

◆ withinEdgeOnSideTempl() [3/3]

template<typename T >
std::enable_if<!std::is_base_of< libMesh::Cell, T >::value, bool >::type TraceRayTools::withinEdgeOnSideTempl ( const Elem * const  elem,
const Point &  point,
const unsigned short  side,
ElemExtrema extrema 
)

Determines if a point is within an edge on the side of an element.

SFINAE here makes this method available for only 1D/2D elem types (not Cell), which do not have edges, therefore this function errors.

Definition at line 1045 of file TraceRayTools.h.

1046{
1047 mooseError("Should not call withinEdgeOnSideTempl() with a non-Cell derived Elem");
1048}

◆ withinEdgeTempl() [1/2]

template<typename T >
bool TraceRayTools::withinEdgeTempl ( const Elem elem,
const Point point,
ElemExtrema extrema,
const Real  tolerance 
)

Definition at line 574 of file TraceRayTools.C.

578{
579 mooseAssert(extrema.isInvalid(), "Should be invalid");
580
581 for (int e = 0; e < T::num_edges; ++e)
582 if (isWithinSegment(elem->point(T::edge_nodes_map[e][0]),
583 elem->point(T::edge_nodes_map[e][1]),
584 point,
585 tolerance))
586 {
587 extrema.setEdge(T::edge_nodes_map[e][0], T::edge_nodes_map[e][1]);
588 return true;
589 }
590
591 return false;
592}

◆ withinEdgeTempl() [2/2]

template<typename T >
bool TraceRayTools::withinEdgeTempl ( const Elem *  elem,
const Point &  point,
ElemExtrema extrema,
const Real  tolerance = TRACE_TOLERANCE 
)

Determines if a point is within edge on an element.

The template argument should be a derived element type that corresponds to the elem->type(), and is used to obtain edge/node mapping without using virtuals.

Parameters
elemThe element
pointThe point
extremaTo be filled with the local vertex IDs that contain the edge the point is within, if any
toleranceThe tolerance to use
Returns
If the point is within an edge of the element

◆ withinExtremaOnSide() [1/2]

bool TraceRayTools::withinExtremaOnSide ( const Elem *const  elem,
const Point &  point,
const unsigned short  side,
const unsigned int  dim,
ElemExtrema extrema 
)

Determines if a point is within an Elem's extrema (at vertex/within edge) on a side.

Parameters
elemThe element
pointThe point
sideThe side
dimThe element dimension
extremaTo be filled with the extrema if any are found
Returns
If the point is at a vertex/within an edge on the side

Referenced by TraceRay::applyOnExternalBoundary(), TraceRay::applyOnInternalBoundary(), and TraceRay::findExternalBoundarySide().

◆ withinExtremaOnSide() [2/2]

bool TraceRayTools::withinExtremaOnSide ( const Elem *const  elem,
const Point point,
const unsigned short  side,
const unsigned int  dim,
ElemExtrema extrema 
)

Definition at line 760 of file TraceRayTools.C.

765{
766 mooseAssert(extrema.isInvalid(), "Extrema should be invalid");
767 mooseAssert(dim == elem->dim(), "Incorrect dim");
768
769 extrema.first = atVertexOnSide(elem, point, side);
770 if (extrema.atVertex())
771 return true;
772 if (dim == 3 && withinEdgeOnSide(elem, point, side, extrema))
773 return true;
774
775 return false;
776}
virtual unsigned short dim() const=0
bool withinEdgeOnSide(const Elem *const elem, const Point &point, const unsigned short side, ElemExtrema &extrema)
Determines if a point is within an edge on the side of an element.
unsigned short atVertexOnSide(const Elem *elem, const Point &point, const unsigned short side)
Determines if a point is at a vertex on the side of en element.
bool atVertex() const
Definition ElemExtrema.h:56

Variable Documentation

◆ ADAPTIVITY_TRACEABLE_ELEMTYPES

const std::set< int > TraceRayTools::ADAPTIVITY_TRACEABLE_ELEMTYPES = {QUAD4, HEX8, TRI3, TET4, EDGE2}

The element types that are traceable with adaptivity.

Definition at line 45 of file TraceRayTools.C.

Referenced by isAdaptivityTraceableElem().

◆ INVALID_INT

const int TraceRayTools::INVALID_INT = std::numeric_limits<int>::max()

Value for an invalid integer.

Definition at line 53 of file TraceRayTools.h.

◆ LOOSE_TRACE_TOLERANCE

const Real TraceRayTools::LOOSE_TRACE_TOLERANCE = 1e-5

◆ TRACE_TOLERANCE

const Real TraceRayTools::TRACE_TOLERANCE = 1e-8

◆ TRACEABLE_ELEMTYPES

const std::set< int > TraceRayTools::TRACEABLE_ELEMTYPES
Initial value:
= {
HEX8, HEX20, HEX27, QUAD4, QUAD8, QUAD9, TET4, TET10, TET14, TRI3, TRI6,
TRI7, EDGE2, EDGE3, EDGE4, PYRAMID5, PYRAMID13, PYRAMID14, PRISM6, PRISM15, PRISM18}

The element types that are traceable.

Definition at line 42 of file TraceRayTools.C.

Referenced by isTraceableElem(), TEST(), TEST(), TEST(), TEST(), and TEST().