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 );
 
  231 template< 
typename CENTER_TYPE, 
typename NORMAL_TYPE >
 
  236                            CENTER_TYPE && center,
 
  237                            NORMAL_TYPE && normal,
 
  238                            real64 const areaTolerance = 0.0 )
 
  241   LvArray::tensorOps::fill< 3 >( center, 0 );
 
  242   LvArray::tensorOps::fill< 3 >( normal, 0 );
 
  244   localIndex const numberOfPoints = pointsIndices.size();
 
  248   real64 current[ 3 ], next[ 3 ], crossProduct[ 3 ];
 
  250   LvArray::tensorOps::copy< 3 >( next, points[ pointsIndices[ numberOfPoints - 1 ] ] );
 
  254     LvArray::tensorOps::copy< 3 >( current, next );
 
  255     LvArray::tensorOps::copy< 3 >( next, points[ pointsIndices[ a ] ] );
 
  257     LvArray::tensorOps::crossProduct( crossProduct, current, next );
 
  259     LvArray::tensorOps::add< 3 >( normal, crossProduct );
 
  260     LvArray::tensorOps::add< 3 >( center, next );
 
  263   area = LvArray::tensorOps::l2Norm< 3 >( normal );
 
  264   LvArray::tensorOps::scale< 3 >( center, 1.0 / numberOfPoints );
 
  266   if( area > areaTolerance )
 
  268     LvArray::tensorOps::normalize< 3 >( normal );
 
  271   else if( area < -areaTolerance )
 
  275       GEOS_LOG_RANK( 
"Points: " << points[ pointsIndices[ a ] ] << 
" " << pointsIndices[ a ] );
 
  277     GEOS_ERROR( 
"Negative area found : " << area );
 
  292 template< 
typename NORMAL_TYPE >
 
  300   if( normal[ 2 ] <= -orientationTolerance )
 
  302     LvArray::tensorOps::scale< 3 >( normal, -1.0 );
 
  304   else if( std::fabs( normal[ 2 ] ) < orientationTolerance )
 
  307     if( normal[ 1 ] <= -orientationTolerance )
 
  309       LvArray::tensorOps::scale< 3 >( normal, -1.0 );
 
  311     else if( fabs( normal[ 1 ] ) < orientationTolerance )
 
  314       if( normal[ 0 ] <= -orientationTolerance )
 
  316         LvArray::tensorOps::scale< 3 >( normal, -1.0 );
 
  329 template< 
typename NORMAL_TYPE, 
typename MATRIX_TYPE >
 
  332                         MATRIX_TYPE && rotationMatrix )
 
  334   real64 m1[ 3 ] = { normal[ 2 ], 0.0, -normal[ 0 ] };
 
  335   real64 m2[ 3 ] = { 0.0, normal[ 2 ], -normal[ 1 ] };
 
  336   real64 const norm_m1 = LvArray::tensorOps::l2Norm< 3 >( m1 );
 
  337   real64 const norm_m2 = LvArray::tensorOps::l2Norm< 3 >( m2 );
 
  343     LvArray::tensorOps::crossProduct( m2, normal, m1 );
 
  344     LvArray::tensorOps::normalize< 3 >( m2 );
 
  345     LvArray::tensorOps::normalize< 3 >( m1 );
 
  349     LvArray::tensorOps::crossProduct( m1, normal, m2 );
 
  350     LvArray::tensorOps::scale< 3 >( m1, -1 );
 
  351     LvArray::tensorOps::normalize< 3 >( m1 );
 
  352     LvArray::tensorOps::normalize< 3 >( m2 );
 
  356   rotationMatrix[ 0 ][ 0 ] = normal[ 0 ];
 
  357   rotationMatrix[ 1 ][ 0 ] = normal[ 1 ];
 
  358   rotationMatrix[ 2 ][ 0 ] = normal[ 2 ];
 
  359   rotationMatrix[ 0 ][ 1 ] = m1[ 0 ];
 
  360   rotationMatrix[ 1 ][ 1 ] = m1[ 1 ];
 
  361   rotationMatrix[ 2 ][ 1 ] = m1[ 2 ];
 
  362   rotationMatrix[ 0 ][ 2 ] = m2[ 0 ];
 
  363   rotationMatrix[ 1 ][ 2 ] = m2[ 1 ];
 
  364   rotationMatrix[ 2 ][ 2 ] = m2[ 2 ];
 
  367                  "Rotation matrix with determinant different from +1.0" );
 
  376 template< 
typename T >
 
  381   return (T( 0 ) < val) - (val < T( 0 ));
 
  397 template< 
typename POINT_TYPE >
 
  402                               POINT_TYPE 
const & elemCenter,
 
  403                               POINT_TYPE 
const & point,
 
  404                               real64 const areaTolerance = 0.0 )
 
  406   localIndex const numFaces = faceIndices.size();
 
  407   R1Tensor faceCenter, faceNormal, cellToFaceVec;
 
  413     centroid_3DPolygon( facesToNodes[faceIndex], nodeCoordinates, faceCenter, faceNormal, areaTolerance );
 
  416     LvArray::tensorOps::copy< 3 >( cellToFaceVec, faceCenter );
 
  417     LvArray::tensorOps::subtract< 3 >( cellToFaceVec, elemCenter );
 
  418     if( LvArray::tensorOps::AiBi< 3 >( cellToFaceVec, faceNormal ) < 0.0 )
 
  420       LvArray::tensorOps::scale< 3 >( faceNormal, -1 );
 
  424     LvArray::tensorOps::subtract< 3 >( faceCenter, point );
 
  425     int const s = 
sign( LvArray::tensorOps::AiBi< 3 >( faceNormal, faceCenter ) );
 
  446 template< 
typename POLYGON_TYPE, 
typename POINT_TYPE >
 
  449                          POINT_TYPE 
const & point,
 
  450                          real64 const tol = 1e-10 )
 
  454   for( 
integer i = 0; i < n; ++i )
 
  456     auto const & p1 = polygon[i];
 
  457     auto const & p2 = polygon[(i + 1) % n];
 
  459     real64 y1 = p1[1], y2 = p2[1];
 
  460     real64 x1 = p1[0], x2 = p2[0];
 
  461     real64 py = point[1], px = point[0];
 
  464     if( py + tol < std::min( y1, y2 ) || py - tol > std::max( y1, y2 ) )
 
  469     if( std::abs( (x2 - x1) * (py - y1) - (px - x1) * (y2 - y1) ) < tol *
 
  470         ( std::hypot( x2 - x1, y2 - y1 ) + 1.0 ) )
 
  473       if( px + tol >= std::min( x1, x2 ) && px - tol <= std::max( x1, x2 ) &&
 
  474           py + tol >= std::min( y1, y2 ) && py - tol <= std::max( y1, y2 ) )
 
  479     if( std::abs( y2 - y1 ) < tol )
 
  483     real64 xIntersect = x1 + (py - y1) * (x2 - x1) / (y2 - y1);
 
  486     if( px < xIntersect - tol )
 
  490   return (count % 2) == 1;
 
  503 template< 
typename POLYGON_TYPE, 
typename POINT_TYPE >
 
  506                          POINT_TYPE 
const & point,
 
  507                          real64 const tol = 1e-10 )
 
  510   auto const & p0 = polygon[0];
 
  511   POINT_TYPE normal = {0, 0, 0};
 
  512   for( 
integer i = 1; i < n - 1; i++ )
 
  514     auto const & p1 = polygon[i];
 
  515     auto const & p2 = polygon[i + 1];
 
  516     normal[0] += (p1[1] - p0[1]) * (p2[2] - p0[2]) - (p1[2] - p0[2]) * (p2[1] - p0[1]);
 
  517     normal[1] += (p1[2] - p0[2]) * (p2[0] - p0[0]) - (p1[0] - p0[0]) * (p2[2] - p0[2]);
 
  518     normal[2] += (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p1[1] - p0[1]) * (p2[0] - p0[0]);
 
  521   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]);
 
  523   if( std::abs( dist ) > tol )
 
  529   int dominantIndex = 0;
 
  530   if( std::abs( normal[1] ) > std::abs( normal[0] ))
 
  534   if( std::abs( normal[2] ) > std::abs( normal[dominantIndex] ))
 
  540   POLYGON_TYPE projectedPolygon( n );
 
  541   POINT_TYPE projectedPoint;
 
  542   if( dominantIndex == 0 )  
 
  544     for( 
int i = 0; i < n; i++ )
 
  546       projectedPolygon[i][0] = polygon[i][1];
 
  547       projectedPolygon[i][1] = polygon[i][2];
 
  549     projectedPoint[0] = point[1];
 
  550     projectedPoint[1] = point[2];
 
  552   else if( dominantIndex == 1 )  
 
  554     for( 
int i = 0; i < n; i++ )
 
  556       projectedPolygon[i][0] = polygon[i][0];
 
  557       projectedPolygon[i][1] = polygon[i][2];
 
  559     projectedPoint[0] = point[0];
 
  560     projectedPoint[1] = point[2];
 
  564     for( 
int i = 0; i < n; i++ )
 
  566       projectedPolygon[i][0] = polygon[i][0];
 
  567       projectedPolygon[i][1] = polygon[i][1];
 
  569     projectedPoint[0] = point[0];
 
  570     projectedPoint[1] = point[1];
 
  588 template< 
typename COORD_TYPE, 
typename POINT_TYPE >
 
  591                                   COORD_TYPE 
const bx, COORD_TYPE 
const by, COORD_TYPE 
const bz )
 
  623 template< 
typename COORD_TYPE, 
typename POINT_TYPE >
 
  626                                 COORD_TYPE 
const e1x, COORD_TYPE 
const e1y, COORD_TYPE 
const e1z,
 
  627                                 COORD_TYPE 
const e2x, COORD_TYPE 
const e2y, COORD_TYPE 
const e2z )
 
  630                                        ( e1z - az ) * ( e2x - ax ),
 
  631                                        ( e1z - az ) * ( e2y - ay ),
 
  632                                        ( e1x - ax ) * ( e2y - ay ),
 
  633                                        ( e1x - ax ) * ( e2z - az ),
 
  634                                        ( e1y - ay ) * ( e2z - az ) );
 
  655 template< 
typename COORD_TYPE, 
typename POINT_TYPE >
 
  658                                     COORD_TYPE 
const t1x, COORD_TYPE 
const t1y, COORD_TYPE 
const t1z,
 
  659                                     COORD_TYPE 
const t2x, COORD_TYPE 
const t2y, COORD_TYPE 
const t2z,
 
  660                                     COORD_TYPE 
const t3x, COORD_TYPE 
const t3y, COORD_TYPE 
const t3z )
 
  662   COORD_TYPE v1x = t1x - ax;
 
  663   COORD_TYPE v1y = t1y - ay;
 
  664   COORD_TYPE v1z = t1z - az;
 
  665   COORD_TYPE v2x = t2x - ax;
 
  666   COORD_TYPE v2y = t2y - ay;
 
  667   COORD_TYPE v2z = t2z - az;
 
  668   COORD_TYPE v3x = t3x - ax;
 
  669   COORD_TYPE v3y = t3y - ay;
 
  670   COORD_TYPE v3z = t3z - az;
 
  671   COORD_TYPE 
sign = ( v1x * v2y - v1y * v2x ) * v3z +
 
  672                     ( v2x * v3y - v2y * v3x ) * v1z +
 
  673                     ( v3x * v1y - v3y * v1x ) * v2z;
 
  687 template< 
typename ... LIST_TYPE >
 
  693   globalIndex minElementGID = LvArray::NumericLimits< globalIndex >::max;
 
  694   for( 
int i = 0; i < nodeElements.size(); i++ )
 
  697     if( elementGlobalIndex[ e ] < minElementGID )
 
  699       minElementGID = elementGlobalIndex[ e ];
 
  714 template< 
typename ... LIST_TYPE >
 
  721   globalIndex minElementGID = LvArray::NumericLimits< globalIndex >::max;
 
  722   for( 
int i = 0; i < nodeElements1.size(); i++ )
 
  725     for( 
int j = 0; j < nodeElements2.size(); j++ )
 
  730         if( elementGlobalIndex[ e1 ] < minElementGID )
 
  732           minElementGID = elementGlobalIndex[ e1 ];
 
  750 template< 
typename ... LIST_TYPE >
 
  758   globalIndex minElementGID = LvArray::NumericLimits< globalIndex >::max;
 
  759   for( 
int i = 0; i < nodeElements1.size(); i++ )
 
  762     for( 
int j = 0; j < nodeElements2.size(); j++ )
 
  765       for( 
int k = 0; k < nodeElements3.size(); k++ )
 
  768         if( e1 == e2 && e2 == e3 )
 
  770           if( elementGlobalIndex[ e1 ] < minElementGID )
 
  772             minElementGID = elementGlobalIndex[ e1 ];
 
  796 template< 
typename COORD_TYPE, 
typename POINT_TYPE >
 
  805                            POINT_TYPE 
const & elemCenter,
 
  806                            POINT_TYPE 
const & point )
 
  809   localIndex const numFaces = faceIndices.size();
 
  816     globalIndex minGlobalId = LvArray::NumericLimits< globalIndex >::max;
 
  818     localIndex numFaceVertices = facesToNodes[faceIndex].size();
 
  819     for( 
localIndex v = 0; v < numFaceVertices; v++ )
 
  821       localIndex vIndex = facesToNodes( faceIndex, v );
 
  822       globalIndex globalId = nodeLocalToGlobal[ vIndex ];
 
  823       if( globalId < minGlobalId )
 
  825         minGlobalId = globalId;
 
  831     for( 
localIndex v = 0; v < numFaceVertices; v++ )
 
  833       vi[ 1 ] = facesToNodes( faceIndex, v );
 
  834       vi[ 2 ] = facesToNodes( faceIndex, (v + 1) % numFaceVertices );
 
  835       if( vi[ 1 ] != minVertex && vi[ 2 ] != minVertex )
 
  838         if( nodeLocalToGlobal[ vi[ 1 ] ] > nodeLocalToGlobal[ vi[ 2 ] ] )
 
  844         COORD_TYPE v1x = nodeCoordinates( vi[ 0 ], 0 );
 
  845         COORD_TYPE v1y = nodeCoordinates( vi[ 0 ], 1 );
 
  846         COORD_TYPE v1z = nodeCoordinates( vi[ 0 ], 2 );
 
  847         COORD_TYPE v2x = nodeCoordinates( vi[ 1 ], 0 );
 
  848         COORD_TYPE v2y = nodeCoordinates( vi[ 1 ], 1 );
 
  849         COORD_TYPE v2z = nodeCoordinates( vi[ 1 ], 2 );
 
  850         COORD_TYPE v3x = nodeCoordinates( vi[ 2 ], 0 );
 
  851         COORD_TYPE v3y = nodeCoordinates( vi[ 2 ], 1 );
 
  852         COORD_TYPE v3z = nodeCoordinates( vi[ 2 ], 2 );
 
  854         R1Tensor vv1 = { v2x - v1x, v2y - v1y, v2z - v1z  };
 
  855         R1Tensor vv2 = { v3x - v1x, v3y - v1y, v3z - v1z  };
 
  856         R1Tensor dist = { elemCenter[ 0 ] - ( v1x + v2x + v3x )/3.0,
 
  857                           elemCenter[ 1 ] - ( v1y + v2y + v3y )/3.0,
 
  858                           elemCenter[ 2 ] - ( v1z + v2z + v3z )/3.0 };
 
  860         LvArray::tensorOps::crossProduct( norm, vv1, vv2 );
 
  862         int sign = LvArray::tensorOps::AiBi< 3 >( norm, dist ) > 0 ? -1 : +1;
 
  888             return findEdgeRefElement( nodesToElements[ vi[ 0 ] ], nodesToElements[ vi[ 1 ] ], elementLocalToGlobal ) == element;
 
  890           facecmp += 
sign * edgecmp;
 
  899             return findEdgeRefElement( nodesToElements[ vi[ 1 ] ], nodesToElements[ vi[ 2 ] ], elementLocalToGlobal ) == element;
 
  901           facecmp += 
sign * edgecmp;
 
  910             return findEdgeRefElement( nodesToElements[ vi[ 0 ] ], nodesToElements[ vi[ 2 ] ], elementLocalToGlobal ) == element;
 
  912           facecmp += 
sign * edgecmp;
 
  924           return findTriangleRefElement( nodesToElements[ vi[ 0 ] ], nodesToElements[ vi[ 1 ] ], nodesToElements[ vi[ 2 ] ], elementLocalToGlobal ) == element;
 
  926         omega += 
sign * facecmp;
 
  957 template< 
typename COORD_TYPE, 
typename POINT_TYPE >
 
  966                                           POINT_TYPE 
const & elemCenter,
 
  967                                           POINT_TYPE 
const & point )
 
  969   return computeWindingNumber( element, nodeCoordinates, elementsToFaces, facesToNodes, nodesToElements, nodeLocalToGlobal, elementLocalToGlobal, elemCenter, point ) > 0;
 
  981 template< 
typename NODE_MAP_TYPE, 
typename VEC_TYPE >
 
  984                      NODE_MAP_TYPE 
const & pointIndices,
 
  986                      VEC_TYPE && boxDims )
 
  989   R1Tensor minCoords = { LvArray::NumericLimits< real64 >::max,
 
  990                          LvArray::NumericLimits< real64 >::max,
 
  991                          LvArray::NumericLimits< real64 >::max };
 
  994   LvArray::tensorOps::fill< 3 >( boxDims, LvArray::NumericLimits< real64 >::lowest );
 
  997   for( 
localIndex a = 0; a < pointIndices[elemIndex].size(); ++a )
 
  999     localIndex const id = pointIndices( elemIndex, a );
 
 1002       minCoords[ d ] = fmin( minCoords[ d ], pointCoordinates( 
id, d ) );
 
 1003       boxDims[ d ] = fmax( boxDims[ d ], pointCoordinates( 
id, d ) );
 
 1007   LvArray::tensorOps::subtract< 3 >( boxDims, minCoords );
 
 1016 template< 
typename FE_TYPE >
 
 1021   for( 
localIndex q=0; q<FE_TYPE::numQuadraturePoints; ++q )
 
 1023     result = result + FE_TYPE::transformedQuadratureWeight( q, X );
 
 1037   return elementVolume< finiteElement::H1_Hexahedron_Lagrange1_GaussLegendre2 >( X );
 
 1049   return elementVolume< finiteElement::H1_Tetrahedron_Lagrange1_Gauss1 >( X );
 
 1061   return elementVolume< finiteElement::H1_Wedge_Lagrange1_Gauss6 >( X );
 
 1073   return elementVolume< finiteElement::H1_Pyramid_Lagrange1_Gauss5 >( X );
 
 1086 template< 
integer N >
 
 1091   static_assert( N > 4,
 
 1092                  "Function prismVolume can be called for a prism with N-sided polygon base where N > 5." );
 
 1099   for( 
integer a = 0; a < N; ++a )
 
 1101     LvArray::tensorOps::add< 3 >( XGBot, X[a] );
 
 1103   for( 
integer a = N; a < 2 * N; ++a )
 
 1105     LvArray::tensorOps::add< 3 >( XGTop, X[a] );
 
 1107   LvArray::tensorOps::scale< 3 >( XGBot, 1.0 / N );
 
 1108   LvArray::tensorOps::scale< 3 >( XGTop, 1.0 / N );
 
 1111   for( 
int a = 0; a < N - 1; ++a )
 
 1114     LvArray::tensorOps::copy< 3 >( XWedge[0], X[a] );
 
 1115     LvArray::tensorOps::copy< 3 >( XWedge[1], X[a+N] );
 
 1116     LvArray::tensorOps::copy< 3 >( XWedge[2], X[a+1] );
 
 1117     LvArray::tensorOps::copy< 3 >( XWedge[3], X[a+1+N] );
 
 1118     LvArray::tensorOps::copy< 3 >( XWedge[4], XGBot );
 
 1119     LvArray::tensorOps::copy< 3 >( XWedge[5], XGTop );
 
 1120     result = result + computationalGeometry::elementVolume< finiteElement::H1_Wedge_Lagrange1_Gauss6 >( XWedge );
 
 1122   LvArray::tensorOps::copy< 3 >( XWedge[0], X[N-1] );
 
 1123   LvArray::tensorOps::copy< 3 >( XWedge[1], X[2*N-1] );
 
 1124   LvArray::tensorOps::copy< 3 >( XWedge[2], X[0] );
 
 1125   LvArray::tensorOps::copy< 3 >( XWedge[3], X[N] );
 
 1126   LvArray::tensorOps::copy< 3 >( XWedge[4], XGBot );
 
 1127   LvArray::tensorOps::copy< 3 >( XWedge[5], XGTop );
 
 1128   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 and the rotation matrix.
 
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_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(msg)
Raise a hard error and terminate the program.
 
#define GEOS_ERROR_IF(EXP, msg)
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.