20 #ifndef GEOS_MESH_UTILITIES_COMPUTATIONALGEOMETRY_HPP_
21 #define GEOS_MESH_UTILITIES_COMPUTATIONALGEOMETRY_HPP_
29 #include "LvArray/src/output.hpp"
30 #include "LvArray/src/tensorOps.hpp"
34 namespace computationalGeometry
53 template<
typename LINEDIR_TYPE,
57 typename INTPOINT_TYPE >
59 POINT_TYPE
const & linePoint,
60 NORMAL_TYPE
const & planeNormal,
61 ORIGIN_TYPE
const & planeOrigin,
62 INTPOINT_TYPE & intersectionPoint )
70 real64 dummy[ 3 ] = LVARRAY_TENSOROPS_INIT_LOCAL_3( planeOrigin );
71 LvArray::tensorOps::subtract< 3 >( dummy, linePoint );
72 real64 const d = LvArray::tensorOps::AiBi< 3 >( dummy, planeNormal ) /
73 LvArray::tensorOps::AiBi< 3 >( lineDir, planeNormal );
75 LvArray::tensorOps::copy< 3 >( intersectionPoint, linePoint );
76 LvArray::tensorOps::scaledAdd< 3 >( intersectionPoint, lineDir, d );
86 template<
typename NORMAL_TYPE >
88 NORMAL_TYPE
const & normal )
99 LvArray::tensorOps::fill< 3 >( centroid, 0 );
102 LvArray::tensorOps::add< 3 >( centroid, points[ a ] );
106 LvArray::tensorOps::scale< 3 >( centroid, 1.0 / numPoints );
108 real64 v0[3] = LVARRAY_TENSOROPS_INIT_LOCAL_3( centroid );
109 LvArray::tensorOps::subtract< 3 >( v0, points[ 0 ] );
110 LvArray::tensorOps::normalize< 3 >( v0 );
116 real64 v[3] = LVARRAY_TENSOROPS_INIT_LOCAL_3( centroid );
117 LvArray::tensorOps::subtract< 3 >( v, points[ a ] );
118 real64 const dot = LvArray::tensorOps::AiBi< 3 >( v, v0 );
121 LvArray::tensorOps::crossProduct( crossProduct, v, v0 );
122 real64 const det = LvArray::tensorOps::AiBi< 3 >( normal, crossProduct );
124 angle[ a ] = std::atan2( det, dot );
128 std::sort( indices.begin(), indices.end(), [&](
int i,
int j ) { return angle[ i ] < angle[ j ]; } );
134 LvArray::tensorOps::copy< 3 >( orderedPoints[ a ], points[ indices[ a ] ] );
139 LvArray::tensorOps::copy< 3 >( points[a], orderedPoints[a] );
152 template<
typename NORMAL_TYPE >
154 NORMAL_TYPE
const && normal )
160 for(
localIndex a = 0; a < points.size( 0 ); a++ )
162 LvArray::tensorOps::copy< 3 >( orderedPoints[a], points[a] );
167 for(
localIndex a = 0; a < points.size( 0 ) - 2; ++a )
169 real64 v1[ 3 ] = LVARRAY_TENSOROPS_INIT_LOCAL_3( orderedPoints[ a + 1 ] );
170 real64 v2[ 3 ] = LVARRAY_TENSOROPS_INIT_LOCAL_3( orderedPoints[ a + 2 ] );
172 LvArray::tensorOps::subtract< 3 >( v1, orderedPoints[ 0 ] );
173 LvArray::tensorOps::subtract< 3 >( v2, orderedPoints[ 0 ] );
175 real64 triangleNormal[ 3 ];
176 LvArray::tensorOps::crossProduct( triangleNormal, v1, v2 );
177 surfaceArea += LvArray::tensorOps::l2Norm< 3 >( triangleNormal );
180 return surfaceArea * 0.5;
191 template< localIndex DIMENSION,
typename POINT_COORDS_TYPE >
198 for(
localIndex numPoint = 0; numPoint < numPoints; ++numPoint )
200 for(
localIndex numOthPoint = 0; numOthPoint < numPoint; ++numOthPoint )
202 real64 candidateDiameter = 0.0;
205 real64 coordDiff = points[numPoint][i] - points[numOthPoint][i];
206 candidateDiameter += coordDiff * coordDiff;
208 if( diameter < candidateDiameter )
210 diameter = candidateDiameter;
214 return LvArray::math::sqrt< real64 >( diameter );
233 template<
typename CENTER_TYPE,
typename NORMAL_TYPE >
238 CENTER_TYPE && center,
239 NORMAL_TYPE && normal,
240 real64 const areaTolerance = 0.0 )
243 LvArray::tensorOps::fill< 3 >( center, 0 );
244 LvArray::tensorOps::fill< 3 >( normal, 0 );
246 localIndex const numberOfPoints = pointsIndices.size();
250 real64 current[ 3 ], next[ 3 ], origin[ 3 ], crossProduct[ 3 ];
254 real64 pairSum[ 3 ], edgeDiff[ 3 ];
255 real64 crossMoment[ 3 ][ 3 ] = {{ 0 }};
256 real64 diffMoment[ 3 ][ 3 ] = {{ 0 }};
258 LvArray::tensorOps::copy< 3 >( next, points[ pointsIndices[ numberOfPoints - 1 ] ] );
259 LvArray::tensorOps::copy< 3 >( origin, points[ pointsIndices[ 0 ]] );
263 LvArray::tensorOps::copy< 3 >( current, points[ pointsIndices[ a++ ]] );
264 LvArray::tensorOps::scaledAdd< 3 >( current, origin, -1. );
265 LvArray::tensorOps::copy< 3 >( next, points[ pointsIndices[ a % numberOfPoints ] ] );
266 LvArray::tensorOps::scaledAdd< 3 >( next, origin, -1. );
268 LvArray::tensorOps::crossProduct( crossProduct, current, next );
270 LvArray::tensorOps::add< 3 >( normal, crossProduct );
271 LvArray::tensorOps::add< 3 >( center, next );
274 LvArray::tensorOps::copy< 3 >( pairSum, current );
275 LvArray::tensorOps::add< 3 >( pairSum, next );
276 LvArray::tensorOps::copy< 3 >( edgeDiff, current );
277 LvArray::tensorOps::subtract< 3 >( edgeDiff, next );
278 LvArray::tensorOps::Rij_add_AiBj< 3, 3 >( crossMoment, pairSum, crossProduct );
279 LvArray::tensorOps::Rij_add_AiBj< 3, 3 >( diffMoment, pairSum, edgeDiff );
282 area = LvArray::tensorOps::l2Norm< 3 >( normal );
283 LvArray::tensorOps::scale< 3 >( center, 1.0 / numberOfPoints );
285 if( area > areaTolerance )
287 LvArray::tensorOps::normalize< 3 >( normal );
292 real64 nxd[ 3 ], firstMoment[ 3 ] = { 0.0 };
293 LvArray::tensorOps::crossProduct( nxd, normal, center );
294 LvArray::tensorOps::Ri_add_AijBj< 3, 3 >( firstMoment, crossMoment, normal );
295 LvArray::tensorOps::Ri_add_AijBj< 3, 3 >( firstMoment, diffMoment, nxd );
297 LvArray::tensorOps::scale< 3 >( center, 1.0 / 3.0 );
298 LvArray::tensorOps::scaledAdd< 3 >( center, firstMoment, 1.0 / ( 6.0 * area ) );
299 LvArray::tensorOps::scaledAdd< 3 >( center, origin, 1. );
301 else if( area < -areaTolerance )
305 GEOS_LOG_RANK(
"Points: " << points[ pointsIndices[ a ] ] <<
" " << pointsIndices[ a ] );
307 #if defined(GEOS_DEVICE_COMPILE)
310 GEOS_ERROR( GEOS_FMT(
"Negative area found : {}", area ) );
317 GEOS_LOG_RANK(
"Points: " << points[ pointsIndices[ a ] ] <<
" " << pointsIndices[ a ] );
319 #if defined(GEOS_DEVICE_COMPILE)
322 GEOS_ERROR( GEOS_FMT(
"Null area found : {}", area ) );
336 template<
typename NORMAL_TYPE >
344 if( normal[ 2 ] <= -orientationTolerance )
346 LvArray::tensorOps::scale< 3 >( normal, -1.0 );
348 else if( std::fabs( normal[ 2 ] ) < orientationTolerance )
351 if( normal[ 1 ] <= -orientationTolerance )
353 LvArray::tensorOps::scale< 3 >( normal, -1.0 );
355 else if( fabs( normal[ 1 ] ) < orientationTolerance )
358 if( normal[ 0 ] <= -orientationTolerance )
360 LvArray::tensorOps::scale< 3 >( normal, -1.0 );
373 template<
typename NORMAL_TYPE,
typename MATRIX_TYPE >
376 MATRIX_TYPE && rotationMatrix )
378 real64 m1[ 3 ] = { normal[ 2 ], 0.0, -normal[ 0 ] };
379 real64 m2[ 3 ] = { 0.0, normal[ 2 ], -normal[ 1 ] };
380 real64 const norm_m1 = LvArray::tensorOps::l2Norm< 3 >( m1 );
381 real64 const norm_m2 = LvArray::tensorOps::l2Norm< 3 >( m2 );
387 LvArray::tensorOps::crossProduct( m2, normal, m1 );
388 LvArray::tensorOps::normalize< 3 >( m2 );
389 LvArray::tensorOps::normalize< 3 >( m1 );
393 LvArray::tensorOps::crossProduct( m1, normal, m2 );
394 LvArray::tensorOps::scale< 3 >( m1, -1 );
395 LvArray::tensorOps::normalize< 3 >( m1 );
396 LvArray::tensorOps::normalize< 3 >( m2 );
400 rotationMatrix[ 0 ][ 0 ] = normal[ 0 ];
401 rotationMatrix[ 1 ][ 0 ] = normal[ 1 ];
402 rotationMatrix[ 2 ][ 0 ] = normal[ 2 ];
403 rotationMatrix[ 0 ][ 1 ] = m1[ 0 ];
404 rotationMatrix[ 1 ][ 1 ] = m1[ 1 ];
405 rotationMatrix[ 2 ][ 1 ] = m1[ 2 ];
406 rotationMatrix[ 0 ][ 2 ] = m2[ 0 ];
407 rotationMatrix[ 1 ][ 2 ] = m2[ 1 ];
408 rotationMatrix[ 2 ][ 2 ] = m2[ 2 ];
411 "Rotation matrix with determinant different from +1.0" );
420 template<
typename T >
425 return (T( 0 ) < val) - (val < T( 0 ));
441 template<
typename POINT_TYPE >
446 POINT_TYPE
const & elemCenter,
447 POINT_TYPE
const & point,
448 real64 const areaTolerance = 0.0 )
450 localIndex const numFaces = faceIndices.size();
451 R1Tensor faceCenter, faceNormal, cellToFaceVec;
457 centroid_3DPolygon( facesToNodes[faceIndex], nodeCoordinates, faceCenter, faceNormal, areaTolerance );
460 LvArray::tensorOps::copy< 3 >( cellToFaceVec, faceCenter );
461 LvArray::tensorOps::subtract< 3 >( cellToFaceVec, elemCenter );
462 if( LvArray::tensorOps::AiBi< 3 >( cellToFaceVec, faceNormal ) < 0.0 )
464 LvArray::tensorOps::scale< 3 >( faceNormal, -1 );
468 LvArray::tensorOps::subtract< 3 >( faceCenter, point );
469 int const s =
sign( LvArray::tensorOps::AiBi< 3 >( faceNormal, faceCenter ) );
490 template<
typename POLYGON_TYPE,
typename POINT_TYPE >
493 POINT_TYPE
const & point,
494 real64 const tol = 1e-10 )
498 for(
integer i = 0; i < n; ++i )
500 auto const & p1 = polygon[i];
501 auto const & p2 = polygon[(i + 1) % n];
503 real64 y1 = p1[1], y2 = p2[1];
504 real64 x1 = p1[0], x2 = p2[0];
505 real64 py = point[1], px = point[0];
508 if( py + tol < std::min( y1, y2 ) || py - tol > std::max( y1, y2 ) )
513 if( std::abs( (x2 - x1) * (py - y1) - (px - x1) * (y2 - y1) ) < tol *
514 ( std::hypot( x2 - x1, y2 - y1 ) + 1.0 ) )
517 if( px + tol >= std::min( x1, x2 ) && px - tol <= std::max( x1, x2 ) &&
518 py + tol >= std::min( y1, y2 ) && py - tol <= std::max( y1, y2 ) )
523 if( std::abs( y2 - y1 ) < tol )
527 real64 xIntersect = x1 + (py - y1) * (x2 - x1) / (y2 - y1);
530 if( px < xIntersect - tol )
534 return (count % 2) == 1;
547 template<
typename POLYGON_TYPE,
typename POINT_TYPE >
550 POINT_TYPE
const & point,
551 real64 const tol = 1e-10 )
554 auto const & p0 = polygon[0];
555 POINT_TYPE normal = {0, 0, 0};
556 for(
integer i = 1; i < n - 1; i++ )
558 auto const & p1 = polygon[i];
559 auto const & p2 = polygon[i + 1];
560 normal[0] += (p1[1] - p0[1]) * (p2[2] - p0[2]) - (p1[2] - p0[2]) * (p2[1] - p0[1]);
561 normal[1] += (p1[2] - p0[2]) * (p2[0] - p0[0]) - (p1[0] - p0[0]) * (p2[2] - p0[2]);
562 normal[2] += (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p1[1] - p0[1]) * (p2[0] - p0[0]);
565 real64 const dist = normal[0] * point[0] + normal[1] * point[1] + normal[2] * point[2] -(normal[0] * p0[0] + normal[1] * p0[1] + normal[2] * p0[2]);
567 if( std::abs( dist ) > tol )
573 int dominantIndex = 0;
574 if( std::abs( normal[1] ) > std::abs( normal[0] ))
578 if( std::abs( normal[2] ) > std::abs( normal[dominantIndex] ))
584 POLYGON_TYPE projectedPolygon( n );
585 POINT_TYPE projectedPoint;
586 if( dominantIndex == 0 )
588 for(
int i = 0; i < n; i++ )
590 projectedPolygon[i][0] = polygon[i][1];
591 projectedPolygon[i][1] = polygon[i][2];
593 projectedPoint[0] = point[1];
594 projectedPoint[1] = point[2];
596 else if( dominantIndex == 1 )
598 for(
int i = 0; i < n; i++ )
600 projectedPolygon[i][0] = polygon[i][0];
601 projectedPolygon[i][1] = polygon[i][2];
603 projectedPoint[0] = point[0];
604 projectedPoint[1] = point[2];
608 for(
int i = 0; i < n; i++ )
610 projectedPolygon[i][0] = polygon[i][0];
611 projectedPolygon[i][1] = polygon[i][1];
613 projectedPoint[0] = point[0];
614 projectedPoint[1] = point[1];
632 template<
typename COORD_TYPE,
typename POINT_TYPE >
635 COORD_TYPE
const bx, COORD_TYPE
const by, COORD_TYPE
const bz )
667 template<
typename COORD_TYPE,
typename POINT_TYPE >
670 COORD_TYPE
const e1x, COORD_TYPE
const e1y, COORD_TYPE
const e1z,
671 COORD_TYPE
const e2x, COORD_TYPE
const e2y, COORD_TYPE
const e2z )
674 ( e1z - az ) * ( e2x - ax ),
675 ( e1z - az ) * ( e2y - ay ),
676 ( e1x - ax ) * ( e2y - ay ),
677 ( e1x - ax ) * ( e2z - az ),
678 ( e1y - ay ) * ( e2z - az ) );
699 template<
typename COORD_TYPE,
typename POINT_TYPE >
702 COORD_TYPE
const t1x, COORD_TYPE
const t1y, COORD_TYPE
const t1z,
703 COORD_TYPE
const t2x, COORD_TYPE
const t2y, COORD_TYPE
const t2z,
704 COORD_TYPE
const t3x, COORD_TYPE
const t3y, COORD_TYPE
const t3z )
706 COORD_TYPE v1x = t1x - ax;
707 COORD_TYPE v1y = t1y - ay;
708 COORD_TYPE v1z = t1z - az;
709 COORD_TYPE v2x = t2x - ax;
710 COORD_TYPE v2y = t2y - ay;
711 COORD_TYPE v2z = t2z - az;
712 COORD_TYPE v3x = t3x - ax;
713 COORD_TYPE v3y = t3y - ay;
714 COORD_TYPE v3z = t3z - az;
715 COORD_TYPE
sign = ( v1x * v2y - v1y * v2x ) * v3z +
716 ( v2x * v3y - v2y * v3x ) * v1z +
717 ( v3x * v1y - v3y * v1x ) * v2z;
731 template<
typename ... LIST_TYPE >
737 globalIndex minElementGID = LvArray::NumericLimits< globalIndex >::max;
738 for(
int i = 0; i < nodeElements.size(); i++ )
741 if( elementGlobalIndex[ e ] < minElementGID )
743 minElementGID = elementGlobalIndex[ e ];
758 template<
typename ... LIST_TYPE >
765 globalIndex minElementGID = LvArray::NumericLimits< globalIndex >::max;
766 for(
int i = 0; i < nodeElements1.size(); i++ )
769 for(
int j = 0; j < nodeElements2.size(); j++ )
774 if( elementGlobalIndex[ e1 ] < minElementGID )
776 minElementGID = elementGlobalIndex[ e1 ];
794 template<
typename ... LIST_TYPE >
802 globalIndex minElementGID = LvArray::NumericLimits< globalIndex >::max;
803 for(
int i = 0; i < nodeElements1.size(); i++ )
806 for(
int j = 0; j < nodeElements2.size(); j++ )
809 for(
int k = 0; k < nodeElements3.size(); k++ )
812 if( e1 == e2 && e2 == e3 )
814 if( elementGlobalIndex[ e1 ] < minElementGID )
816 minElementGID = elementGlobalIndex[ e1 ];
840 template<
typename COORD_TYPE,
typename POINT_TYPE >
849 POINT_TYPE
const & elemCenter,
850 POINT_TYPE
const & point )
853 localIndex const numFaces = faceIndices.size();
860 globalIndex minGlobalId = LvArray::NumericLimits< globalIndex >::max;
862 localIndex numFaceVertices = facesToNodes[faceIndex].size();
863 for(
localIndex v = 0; v < numFaceVertices; v++ )
865 localIndex vIndex = facesToNodes( faceIndex, v );
866 globalIndex globalId = nodeLocalToGlobal[ vIndex ];
867 if( globalId < minGlobalId )
869 minGlobalId = globalId;
875 for(
localIndex v = 0; v < numFaceVertices; v++ )
877 vi[ 1 ] = facesToNodes( faceIndex, v );
878 vi[ 2 ] = facesToNodes( faceIndex, (v + 1) % numFaceVertices );
879 if( vi[ 1 ] != minVertex && vi[ 2 ] != minVertex )
882 if( nodeLocalToGlobal[ vi[ 1 ] ] > nodeLocalToGlobal[ vi[ 2 ] ] )
888 COORD_TYPE v1x = nodeCoordinates( vi[ 0 ], 0 );
889 COORD_TYPE v1y = nodeCoordinates( vi[ 0 ], 1 );
890 COORD_TYPE v1z = nodeCoordinates( vi[ 0 ], 2 );
891 COORD_TYPE v2x = nodeCoordinates( vi[ 1 ], 0 );
892 COORD_TYPE v2y = nodeCoordinates( vi[ 1 ], 1 );
893 COORD_TYPE v2z = nodeCoordinates( vi[ 1 ], 2 );
894 COORD_TYPE v3x = nodeCoordinates( vi[ 2 ], 0 );
895 COORD_TYPE v3y = nodeCoordinates( vi[ 2 ], 1 );
896 COORD_TYPE v3z = nodeCoordinates( vi[ 2 ], 2 );
898 R1Tensor vv1 = { v2x - v1x, v2y - v1y, v2z - v1z };
899 R1Tensor vv2 = { v3x - v1x, v3y - v1y, v3z - v1z };
900 R1Tensor dist = { elemCenter[ 0 ] - ( v1x + v2x + v3x )/3.0,
901 elemCenter[ 1 ] - ( v1y + v2y + v3y )/3.0,
902 elemCenter[ 2 ] - ( v1z + v2z + v3z )/3.0 };
904 LvArray::tensorOps::crossProduct( norm, vv1, vv2 );
906 int sign = LvArray::tensorOps::AiBi< 3 >( norm, dist ) > 0 ? -1 : +1;
932 return findEdgeRefElement( nodesToElements[ vi[ 0 ] ], nodesToElements[ vi[ 1 ] ], elementLocalToGlobal ) == element;
934 facecmp +=
sign * edgecmp;
943 return findEdgeRefElement( nodesToElements[ vi[ 1 ] ], nodesToElements[ vi[ 2 ] ], elementLocalToGlobal ) == element;
945 facecmp +=
sign * edgecmp;
954 return findEdgeRefElement( nodesToElements[ vi[ 0 ] ], nodesToElements[ vi[ 2 ] ], elementLocalToGlobal ) == element;
956 facecmp +=
sign * edgecmp;
968 return findTriangleRefElement( nodesToElements[ vi[ 0 ] ], nodesToElements[ vi[ 1 ] ], nodesToElements[ vi[ 2 ] ], elementLocalToGlobal ) == element;
970 omega +=
sign * facecmp;
1001 template<
typename COORD_TYPE,
typename POINT_TYPE >
1010 POINT_TYPE
const & elemCenter,
1011 POINT_TYPE
const & point )
1013 return computeWindingNumber( element, nodeCoordinates, elementsToFaces, facesToNodes, nodesToElements, nodeLocalToGlobal, elementLocalToGlobal, elemCenter, point ) > 0;
1025 template<
typename NODE_MAP_TYPE,
typename VEC_TYPE >
1028 NODE_MAP_TYPE
const & pointIndices,
1030 VEC_TYPE && boxDims )
1033 R1Tensor minCoords = { LvArray::NumericLimits< real64 >::max,
1034 LvArray::NumericLimits< real64 >::max,
1035 LvArray::NumericLimits< real64 >::max };
1038 LvArray::tensorOps::fill< 3 >( boxDims, LvArray::NumericLimits< real64 >::lowest );
1041 for(
localIndex a = 0; a < pointIndices[elemIndex].size(); ++a )
1043 localIndex const id = pointIndices( elemIndex, a );
1046 minCoords[ d ] = fmin( minCoords[ d ], pointCoordinates(
id, d ) );
1047 boxDims[ d ] = fmax( boxDims[ d ], pointCoordinates(
id, d ) );
1051 LvArray::tensorOps::subtract< 3 >( boxDims, minCoords );
1060 template<
typename FE_TYPE >
1065 for(
localIndex q=0; q<FE_TYPE::numQuadraturePoints; ++q )
1067 result = result + FE_TYPE::transformedQuadratureWeight( q, X );
1081 return elementVolume< finiteElement::H1_Hexahedron_Lagrange1_GaussLegendre2 >( X );
1093 return elementVolume< finiteElement::H1_Tetrahedron_Lagrange1_Gauss1 >( X );
1105 return elementVolume< finiteElement::H1_Wedge_Lagrange1_Gauss6 >( X );
1117 return elementVolume< finiteElement::H1_Pyramid_Lagrange1_Gauss5 >( X );
1130 template<
integer N >
1135 static_assert( N > 4,
1136 "Function prismVolume can be called for a prism with N-sided polygon base where N > 5." );
1143 for(
integer a = 0; a < N; ++a )
1145 LvArray::tensorOps::add< 3 >( XGBot, X[a] );
1147 for(
integer a = N; a < 2 * N; ++a )
1149 LvArray::tensorOps::add< 3 >( XGTop, X[a] );
1151 LvArray::tensorOps::scale< 3 >( XGBot, 1.0 / N );
1152 LvArray::tensorOps::scale< 3 >( XGTop, 1.0 / N );
1155 for(
int a = 0; a < N - 1; ++a )
1158 LvArray::tensorOps::copy< 3 >( XWedge[0], X[a] );
1159 LvArray::tensorOps::copy< 3 >( XWedge[1], X[a+N] );
1160 LvArray::tensorOps::copy< 3 >( XWedge[2], X[a+1] );
1161 LvArray::tensorOps::copy< 3 >( XWedge[3], X[a+1+N] );
1162 LvArray::tensorOps::copy< 3 >( XWedge[4], XGBot );
1163 LvArray::tensorOps::copy< 3 >( XWedge[5], XGTop );
1164 result = result + computationalGeometry::elementVolume< finiteElement::H1_Wedge_Lagrange1_Gauss6 >( XWedge );
1166 LvArray::tensorOps::copy< 3 >( XWedge[0], X[N-1] );
1167 LvArray::tensorOps::copy< 3 >( XWedge[1], X[2*N-1] );
1168 LvArray::tensorOps::copy< 3 >( XWedge[2], X[0] );
1169 LvArray::tensorOps::copy< 3 >( XWedge[3], X[N] );
1170 LvArray::tensorOps::copy< 3 >( XWedge[4], XGBot );
1171 LvArray::tensorOps::copy< 3 >( XWedge[5], XGTop );
1172 result = result + computationalGeometry::elementVolume< finiteElement::H1_Wedge_Lagrange1_Gauss6 >( XWedge );
GEOS_HOST_DEVICE int lexicographicalCompareTriangle(POINT_TYPE const ax, POINT_TYPE const ay, POINT_TYPE const az, COORD_TYPE const t1x, COORD_TYPE const t1y, COORD_TYPE const t1z, COORD_TYPE const t2x, COORD_TYPE const t2y, COORD_TYPE const t2z, COORD_TYPE const t3x, COORD_TYPE const t3y, COORD_TYPE const t3z)
Method to perform lexicographic comparison of a node and a triangle based on coordinates.
GEOS_HOST_DEVICE void getBoundingBox(localIndex const elemIndex, NODE_MAP_TYPE const &pointIndices, arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const &pointCoordinates, VEC_TYPE &&boxDims)
Compute the dimensions of the bounding box containing the element defined here by the coordinates of ...
GEOS_HOST_DEVICE bool isPointInsideConvexPolyhedronRobust(localIndex element, arrayView2d< COORD_TYPE const, nodes::REFERENCE_POSITION_USD > const &nodeCoordinates, arrayView2d< localIndex const > const &elementsToFaces, ArrayOfArraysView< localIndex const > const &facesToNodes, ArrayOfArraysView< localIndex const > const &nodesToElements, arrayView1d< globalIndex const > const &nodeLocalToGlobal, arrayView1d< globalIndex const > const &elementLocalToGlobal, POINT_TYPE const &elemCenter, POINT_TYPE const &point)
Check if a point is inside a convex polyhedron (3D polygon), using a robust method to avoid ambiguity...
GEOS_HOST_DEVICE void FixNormalOrientation_3D(NORMAL_TYPE &&normal)
Change the orientation of the input vector to be consistent in a global sense.
bool isPointInPolygon3d(POLYGON_TYPE const &polygon, integer const n, POINT_TYPE const &point, real64 const tol=1e-10)
Check if a point is inside a polygon (3D version)
GEOS_HOST_DEVICE real64 prismVolume(real64 const (&X)[2 *N][3])
Compute the volume of a prism with N-sided polygon base.
GEOS_HOST_DEVICE bool isPointInsidePolyhedron(arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const &nodeCoordinates, arraySlice1d< localIndex const > const &faceIndices, ArrayOfArraysView< localIndex const > const &facesToNodes, POINT_TYPE const &elemCenter, POINT_TYPE const &point, real64 const areaTolerance=0.0)
Check if a point is inside a convex polyhedron (3D polygon)
GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 centroid_3DPolygon(arraySlice1d< localIndex const > const pointsIndices, arrayView2d< real64 const, nodes::REFERENCE_POSITION_USD > const &points, CENTER_TYPE &¢er, NORMAL_TYPE &&normal, real64 const areaTolerance=0.0)
Calculate the centroid of a convex 3D polygon as well as the normal.
GEOS_HOST_DEVICE void RotationMatrix_3D(NORMAL_TYPE const &normal, MATRIX_TYPE &&rotationMatrix)
Calculate the rotation matrix for a face in the 3D space.
GEOS_HOST_DEVICE bool computeWindingNumber(localIndex element, arrayView2d< COORD_TYPE const, nodes::REFERENCE_POSITION_USD > const &nodeCoordinates, arrayView2d< localIndex const > const &elementsToFaces, ArrayOfArraysView< localIndex const > const &facesToNodes, ArrayOfArraysView< localIndex const > const &nodesToElements, arrayView1d< globalIndex const > const &nodeLocalToGlobal, arrayView1d< globalIndex const > const &elementLocalToGlobal, POINT_TYPE const &elemCenter, POINT_TYPE const &point)
Computes the winding number of a point with respect to a mesh element.
GEOS_HOST_DEVICE int findVertexRefElement(arraySlice1d< localIndex const > const &nodeElements, arrayView1d< globalIndex const > const &elementGlobalIndex)
Method to find the reference element touching a vertex. The element with the lowest global ID is chos...
bool isPointInPolygon2d(POLYGON_TYPE const &polygon, integer n, POINT_TYPE const &point, real64 const tol=1e-10)
Check if a point is inside a polygon (2D version)
constexpr real64 machinePrecision
Machine epsilon for double-precision calculations.
GEOS_HOST_DEVICE real64 elementVolume(real64 const (&X)[FE_TYPE::numNodes][3])
Compute the volume of an element (tetrahedron, pyramid, wedge, hexahedron)
GEOS_HOST_DEVICE int findTriangleRefElement(arraySlice1d< localIndex const > const &nodeElements1, arraySlice1d< localIndex const > const &nodeElements2, arraySlice1d< localIndex const > const &nodeElements3, arrayView1d< globalIndex const > const &elementGlobalIndex)
Method to find the reference element for a triangle. The element with the lowest global ID is chosen ...
GEOS_HOST_DEVICE real64 hexahedronVolume(real64 const (&X)[8][3])
Compute the volume of an hexahedron.
array1d< int > orderPointsCCW(arrayView2d< real64 > const &points, NORMAL_TYPE const &normal)
Reorder a set of points counter-clockwise.
GEOS_HOST_DEVICE int lexicographicalCompareVertex(POINT_TYPE const ax, POINT_TYPE const ay, POINT_TYPE const az, COORD_TYPE const bx, COORD_TYPE const by, COORD_TYPE const bz)
Method to perform lexicographic comparison of two nodes based on coordinates.
GEOS_HOST_DEVICE real64 tetrahedronVolume(real64 const (&X)[4][3])
Compute the volume of an tetrahedron.
void LinePlaneIntersection(LINEDIR_TYPE const &lineDir, POINT_TYPE const &linePoint, NORMAL_TYPE const &planeNormal, ORIGIN_TYPE const &planeOrigin, INTPOINT_TYPE &intersectionPoint)
Calculate the intersection between a line and a plane.
GEOS_HOST_DEVICE int findEdgeRefElement(arraySlice1d< localIndex const > const &nodeElements1, arraySlice1d< localIndex const > const &nodeElements2, arrayView1d< globalIndex const > const &elementGlobalIndex)
Method to find the reference element for an edge. The element with the lowest global ID is chosen fro...
real64 ComputeSurfaceArea(arrayView2d< real64 const > const &points, NORMAL_TYPE const &&normal)
Calculate the area of a polygon given the set of points in ccw order defining it.
GEOS_HOST_DEVICE real64 wedgeVolume(real64 const (&X)[6][3])
Compute the volume of a wedge.
GEOS_HOST_DEVICE real64 pyramidVolume(real64 const (&X)[5][3])
Compute the volume of a pyramid.
GEOS_HOST_DEVICE GEOS_FORCE_INLINE real64 computeDiameter(POINT_COORDS_TYPE points, localIndex const &numPoints)
Calculate the diameter of a set of points in a given dimension.
GEOS_HOST_DEVICE GEOS_FORCE_INLINE int sign(T const val)
Return the sign of a given value as an integer.
GEOS_HOST_DEVICE int lexicographicalCompareEdge(POINT_TYPE const ax, POINT_TYPE const ay, POINT_TYPE const az, COORD_TYPE const e1x, COORD_TYPE const e1y, COORD_TYPE const e1z, COORD_TYPE const e2x, COORD_TYPE const e2y, COORD_TYPE const e2z)
Method to perform lexicographic comparison of a node and an edge based on coordinates.
#define GEOS_HOST_DEVICE
Marks a host-device function.
#define GEOS_FORCE_INLINE
Marks a function or lambda for inlining.
#define GEOS_ERROR(...)
Raise a hard error and terminate the program.
#define GEOS_LOG_RANK(msg)
Log a message to the rank output stream.
#define GEOS_ERROR_IF_LT(lhs, rhs)
Raise a hard error if one value compares less than the other.
#define GEOS_ERROR_IF(COND,...)
Conditionally raise a hard error and terminate the program.
ArrayView< T, 1 > arrayView1d
Alias for 1D array view.
Array< T, 2, PERMUTATION > array2d
Alias for 2D array.
GEOS_GLOBALINDEX_TYPE globalIndex
Global index type (for indexing objects across MPI partitions).
LvArray::ArrayOfArraysView< T, INDEX_TYPE const, CONST_SIZES, LvArray::ChaiBuffer > ArrayOfArraysView
View of array of variable-sized arrays. See LvArray::ArrayOfArraysView for details.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
ArraySlice< T, 1, USD > arraySlice1d
Alias for 1D array slice.
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
int integer
Signed integer type.
Array< T, 1 > array1d
Alias for 1D array.