https://mooseframework.inl.gov
Loading...
Searching...
No Matches
TraceRayTools.h
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
3//*
4//* All rights reserved, see COPYRIGHT for full restrictions
5//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6//*
7//* Licensed under LGPL 2.1, please see LICENSE for details
8//* https://www.gnu.org/licenses/lgpl-2.1.html
9
10#pragma once
11
12// MOOSE includes
14#include "Conversion.h"
15#include "MooseTypes.h"
17
18// Local includes
19#include "DebugRay.h"
20#include "ElemExtrema.h"
21#include "RayTracingCommon.h"
22#include "NeighborInfo.h"
23
24// libMesh includes
25#include "libmesh/face.h"
26#include "libmesh/cell_hex.h"
27#include "libmesh/cell_prism.h"
28#include "libmesh/cell_pyramid.h"
29#include "libmesh/cell_tet.h"
30#include "libmesh/remote_elem.h"
31
32namespace libMesh
33{
34class Mesh;
35class Edge;
36class Cell;
37}
38
40{
41
43extern const std::set<int> TRACEABLE_ELEMTYPES;
45extern const std::set<int> ADAPTIVITY_TRACEABLE_ELEMTYPES;
46
48const Real TRACE_TOLERANCE = 1e-8;
50const Real LOOSE_TRACE_TOLERANCE = 1e-5;
51
53const int INVALID_INT = std::numeric_limits<int>::max();
54
64
82bool lineLineIntersect2D(const Point & start,
83 const Point & direction,
84 const Real length,
85 const Point & v0,
86 const Point & v1,
87 Point & intersection_point,
88 Real & intersection_distance,
89 SegmentVertices & segment_vertex
90#ifdef DEBUG_RAY_INTERSECTIONS
91 ,
92 const bool debug
93#endif
94);
95
104bool isWithinSegment(const Point & segment1,
105 const Point & segment2,
106 const Point & point,
107 const Real tolerance = TRACE_TOLERANCE);
108
118bool isWithinSegment(const Point & segment1,
119 const Point & segment2,
120 const Real segment_length,
121 const Point & point,
122 const Real tolerance = TRACE_TOLERANCE);
123
136 const Elem * const elem,
137 const Point & point,
141 std::vector<const Elem *> active_neighbor_children,
142 std::vector<NeighborInfo> & info);
143
145 const Elem * const elem,
146 const Node * const node,
150 std::vector<const Elem *> active_neighbor_children,
151 std::vector<NeighborInfo> & info);
152
154 const Elem * const elem,
155 const Node * const node1,
156 const Node * const node2,
160 std::vector<const Elem *> active_neighbor_children,
161 std::vector<NeighborInfo> & info);
162
177template <typename KeepFunctor>
178void
180 const Elem * const elem,
184 std::vector<const Elem *> active_neighbor_children,
185 KeepFunctor & keep_functor)
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}
231
232template <typename T>
233bool
234findEdgeNeighborsWithinEdgeInternal(const Elem * const candidate,
235 const Elem * const elem,
236 const Node * const vertex1,
237 const Node * const vertex2,
238 const Real edge_length,
239 std::vector<NeighborInfo> & info)
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}
457
465const Elem *
466childContainingPointOnSide(const Elem * elem, const Point & point, const unsigned short side);
467
476const Elem * getActiveNeighbor(const Elem * elem, const unsigned short side, const Point & point);
477
494bool intersectTriangle(const Point & start,
495 const Point & direction,
496 const Elem * const elem,
497 const unsigned short v0,
498 const unsigned short v1,
499 const unsigned short v2,
500 Real & intersection_distance,
501 ElemExtrema & intersected_extrema,
502 const Real hmax
503#ifdef DEBUG_RAY_INTERSECTIONS
504 ,
505 const bool debug
506#endif
507);
508
533bool intersectQuad(const Point & start,
534 const Point & direction,
535 const Elem * const elem,
536 const unsigned short v00,
537 const unsigned short v10,
538 const unsigned short v11,
539 const unsigned short v01,
540 Real & intersection_distance,
541 ElemExtrema & intersected_extrema,
542 const Real hmax
543#ifdef DEBUG_RAY_INTERSECTIONS
544 ,
545 const bool debug
546#endif
547);
548
562template <typename T>
563typename std::enable_if<std::is_base_of<libMesh::Face, T>::value, bool>::type
564sideIntersectedByLine(const Elem * elem,
565 const Point & start_point,
566 const Point & direction,
567 const unsigned short side,
568 const Real max_length,
569 Point & intersection_point,
570 Real & intersection_distance,
571 ElemExtrema & intersected_extrema,
572 const Real /* hmax */
573#ifdef DEBUG_RAY_INTERSECTIONS
574 ,
575 const bool debug
576#endif
577)
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}
610
623template <typename T>
624typename std::enable_if<std::is_base_of<Hex, T>::value, bool>::type
625sideIntersectedByLine(const Elem * elem,
626 const Point & start_point,
627 const Point & direction,
628 const unsigned short side,
629 const Real,
630 Point & intersection_point,
631 Real & intersection_distance,
632 ElemExtrema & intersected_extrema,
633 const Real hmax
634#ifdef DEBUG_RAY_INTERSECTIONS
635 ,
636 const bool debug
637#endif
638)
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}
665
680template <typename T>
681typename std::enable_if<std::is_base_of<Tet, T>::value, bool>::type
682sideIntersectedByLine(const Elem * elem,
683 const Point & start_point,
684 const Point & direction,
685 const unsigned short side,
686 const Real /* max_length */,
687 Point & intersection_point,
688 Real & intersection_distance,
689 ElemExtrema & intersected_extrema,
690 const Real hmax
691#ifdef DEBUG_RAY_INTERSECTIONS
692 ,
693 const bool debug
694#endif
695)
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}
721
736template <typename T>
737typename std::enable_if<std::is_base_of<libMesh::Pyramid, T>::value, bool>::type
738sideIntersectedByLine(const Elem * elem,
739 const Point & start_point,
740 const Point & direction,
741 const unsigned short side,
742 const Real /* max_length */,
743 Point & intersection_point,
744 Real & intersection_distance,
745 ElemExtrema & intersected_extrema,
746 const Real hmax
747#ifdef DEBUG_RAY_INTERSECTIONS
748 ,
749 const bool debug
750#endif
751)
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}
792
807template <typename T>
808typename std::enable_if<std::is_base_of<libMesh::Prism, T>::value, bool>::type
809sideIntersectedByLine(const Elem * elem,
810 const Point & start_point,
811 const Point & direction,
812 const unsigned short side,
813 const Real /* max_length */,
814 Point & intersection_point,
815 Real & intersection_distance,
816 ElemExtrema & intersected_extrema,
817 const Real hmax
818#ifdef DEBUG_RAY_INTERSECTIONS
819 ,
820 const bool debug
821#endif
822)
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}
863
867bool isTraceableElem(const Elem * elem);
871bool isAdaptivityTraceableElem(const Elem * elem);
872
879unsigned short atVertex(const Elem * elem, const Point & point);
880
888unsigned short atVertexOnSide(const Elem * elem, const Point & point, const unsigned short side);
889
893template <typename T>
894inline typename std::enable_if<!std::is_base_of<libMesh::Pyramid, T>::value &&
895 !std::is_base_of<libMesh::Prism, T>::value,
896 unsigned short>::type
897nodesPerSide(const unsigned short)
898{
899 return T::nodes_per_side;
900}
901
905template <typename T>
906inline typename std::enable_if<std::is_base_of<Pyramid, T>::value, unsigned short>::type
907nodesPerSide(const unsigned short side)
908{
909 return T::nodes_per_side - (side != 4);
910}
911
915template <typename T>
916inline typename std::enable_if<std::is_base_of<libMesh::Prism, T>::value, unsigned short>::type
917nodesPerSide(const unsigned short side)
918{
919 return T::nodes_per_side - (side == 0 || side == 4);
920}
921
935template <typename T>
936typename std::enable_if<!std::is_base_of<Edge, T>::value, unsigned short>::type
937atVertexOnSideTempl(const Elem * elem, const Point & point, const unsigned short side);
938
952template <typename T>
953typename std::enable_if<std::is_base_of<Edge, T>::value, unsigned short>::type
954atVertexOnSideTempl(const Elem * elem, const Point & point, const unsigned short side);
955
969template <typename T>
970bool withinEdgeTempl(const Elem * elem,
971 const Point & point,
972 ElemExtrema & extrema,
973 const Real tolerance = TRACE_TOLERANCE);
974
984bool withinEdge(const Elem * elem,
985 const Point & point,
986 ElemExtrema & extrema,
987 const Real tolerance = TRACE_TOLERANCE);
988
998bool withinEdgeOnSide(const Elem * const elem,
999 const Point & point,
1000 const unsigned short side,
1001 ElemExtrema & extrema);
1002
1012bool withinExtremaOnSide(const Elem * const elem,
1013 const Point & point,
1014 const unsigned short side,
1015 const unsigned int dim,
1016 ElemExtrema & extrema);
1017
1033template <typename T>
1034typename std::enable_if<std::is_base_of<libMesh::Cell, T>::value, bool>::type withinEdgeOnSideTempl(
1035 const Elem * const elem, const Point & point, const unsigned short side, ElemExtrema & extrema);
1036
1043template <typename T>
1044typename std::enable_if<!std::is_base_of<libMesh::Cell, T>::value, bool>::type
1045withinEdgeOnSideTempl(const Elem * const, const Point &, const unsigned short, ElemExtrema &)
1046{
1047 mooseError("Should not call withinEdgeOnSideTempl() with a non-Cell derived Elem");
1048}
1049
1055bool onBoundingBoxBoundary(const BoundingBox & bbox,
1056 const Point & point,
1057 const unsigned int dim,
1058 const Real tolerance);
1059
1060}
const double T
void mooseError(Args &&... args)
char ** sides
bool contains(const T &value) const
void swap(StaticallyAllocatedSet< T, N > &other)
std::string stringify(const T &t)
static const libMesh::Point invalid_point(invalid_distance, invalid_distance, invalid_distance)
Identifier for an invalid point.
static const unsigned short invalid_edge
Identifier for an invalid edge index.
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.
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)
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.
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.
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.
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.
const int INVALID_INT
Value for an invalid integer.
const Real TRACE_TOLERANCE
The standard tolerance to use in tracing.
unsigned short atVertex(const Elem *elem, const Point &point)
Determines if a point is at a vertex of an element.
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.
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.
bool isAdaptivityTraceableElem(const Elem *elem)
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...
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:
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.
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.
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 ele...
const Real LOOSE_TRACE_TOLERANCE
Looser tolerance for use in error checking in difficult situations.
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 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 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)
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: re...
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 std::set< int > TRACEABLE_ELEMTYPES
The element types that are traceable.
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.
const std::set< int > ADAPTIVITY_TRACEABLE_ELEMTYPES
The element types that are traceable with adaptivity.
bool isTraceableElem(const Elem *elem)
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)
SegmentVertices
Enum for the possible vertices on a segment used in lineLineIntersect2D()
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.
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
Helper for defining if at an element's edge, vertex, or neither.
Definition ElemExtrema.h:26
bool isInvalid() const
Definition ElemExtrema.h:48
const Point & vertexPoint(const libMesh::Elem *elem) const
Definition ElemExtrema.C:16
void setVertex(const unsigned short vertex)
Sets the "at vertex" state.