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.
 

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()

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)

Definition at line 561 of file TraceRayTools.C.

562{
563 for (unsigned int v = 0; v < elem->n_vertices(); ++v)
564 if (elem->point(v).absolute_fuzzy_equals(point, TRACE_TOLERANCE))
565 return v;
566
568}
const double v
static const unsigned short invalid_vertex
Identifier for an invalid vertex index.

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

◆ atVertexOnSide()

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)

Definition at line 626 of file TraceRayTools.C.

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

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

◆ atVertexOnSideTempl() [1/2]

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)

Definition at line 669 of file TraceRayTools.C.

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

◆ atVertexOnSideTempl() [2/2]

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)

Definition at line 684 of file TraceRayTools.C.

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

◆ childContainingPointOnSide()

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

Definition at line 327 of file TraceRayTools.C.

328{
329 mooseAssert(!elem->active(), "Should be inactive");
330 mooseAssert(elem->side_ptr(side)->contains_point(point), "Side should contain point");
331
332 for (unsigned int c = 0; c < elem->n_children(); ++c)
333 {
334 if (!elem->is_child_on_side(c, side))
335 continue;
336
337 const auto child = elem->child_ptr(c);
338 // Experience shows that we need to loosen this tolerance just a little
339 // The default is libMesh::TOLERANCE = 1e-6
340 if (child->close_to_point(point, 5.e-5))
341 {
342 if (child->active())
343 return child;
344 else
345 return childContainingPointOnSide(child, point, side);
346 }
347 }
348
349 mooseError("Failed to find child containing point on side");
350}
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.

Referenced by childContainingPointOnSide(), and getActiveNeighbor().

◆ findEdgeNeighbors()

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 252 of file TraceRayTools.C.

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

Referenced by TraceRay::getEdgeNeighbors().

◆ 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 = cast_ptr<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)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real

◆ 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()

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 177 of file TraceRayTools.C.

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

Referenced by TraceRay::getVertexNeighbors().

◆ findPointNeighbors()

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

Definition at line 116 of file TraceRayTools.C.

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

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

◆ getActiveNeighbor()

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

Definition at line 353 of file TraceRayTools.C.

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

Referenced by TraceRay::trace().

◆ intersectQuad()

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

Definition at line 474 of file TraceRayTools.C.

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

Referenced by sideIntersectedByLine().

◆ intersectTriangle()

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

Definition at line 365 of file TraceRayTools.C.

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

Referenced by intersectQuad(), and sideIntersectedByLine().

◆ isAdaptivityTraceableElem()

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

Definition at line 555 of file TraceRayTools.C.

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

Referenced by RayTracingStudy::traceableMeshChecks().

◆ isTraceableElem()

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

Definition at line 549 of file TraceRayTools.C.

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

Referenced by RayTracingStudy::traceableMeshChecks().

◆ isWithinSegment() [1/2]

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]

Definition at line 777 of file TraceRayTools.C.

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

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

◆ isWithinSegment() [2/2]

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]

Definition at line 789 of file TraceRayTools.C.

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

◆ lineLineIntersect2D()

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

Definition at line 46 of file TraceRayTools.C.

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

Referenced by sideIntersectedByLine().

◆ 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()

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.

Definition at line 809 of file TraceRayTools.C.

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

Referenced by TraceRay::trace().

◆ 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()

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

Definition at line 593 of file TraceRayTools.C.

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

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

◆ withinEdgeOnSide()

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

Definition at line 697 of file TraceRayTools.C.

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

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

◆ withinEdgeOnSideTempl() [1/2]

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

Definition at line 731 of file TraceRayTools.C.

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

◆ withinEdgeOnSideTempl() [2/2]

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

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()

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

Definition at line 572 of file TraceRayTools.C.

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

◆ withinExtremaOnSide()

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

Definition at line 758 of file TraceRayTools.C.

763{
764 mooseAssert(extrema.isInvalid(), "Extrema should be invalid");
765 mooseAssert(dim == elem->dim(), "Incorrect dim");
766
767 extrema.first = atVertexOnSide(elem, point, side);
768 if (extrema.atVertex())
769 return true;
770 if (dim == 3 && withinEdgeOnSide(elem, point, side, extrema))
771 return true;
772
773 return false;
774}
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

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

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 43 of file TraceRayTools.C.

43{QUAD4, HEX8, TRI3, TET4, EDGE2};

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 40 of file TraceRayTools.C.

40 {
41 HEX8, HEX20, HEX27, QUAD4, QUAD8, QUAD9, TET4, TET10, TET14, TRI3, TRI6,
42 TRI7, EDGE2, EDGE3, EDGE4, PYRAMID5, PYRAMID13, PYRAMID14, PRISM6, PRISM15, PRISM18};

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