20 #ifndef GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_Q1HEXAHEDRON_HPP_
21 #define GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_Q1HEXAHEDRON_HPP_
43 template<
typename GL_BASIS >
46 GL_BASIS::TensorProduct3D::numSupportPoints >
52 GL_BASIS::TensorProduct3D::numSupportPoints >;
76 template<
typename SubregionType >
180 GL_BASIS::TensorProduct3D::value( coords, N );
193 const real64 alpha = ( GL_BASIS::parentSupportCoord( q ) + 1.0 ) / 2.0;
194 return k == 0 ? ( 1.0 - alpha ) : alpha;
210 return GL_BASIS::gradientAt( q, p );
214 return -GL_BASIS::gradientAt( GL_BASIS::numSupportPoints - 1 - q, GL_BASIS::numSupportPoints - 1 - p );
235 return k== 0 ? -1.0/2.0 : 1.0/2.0;
277 return calcN( q, N );
448 return LvArray::tensorOps::invert< 3 >( J );
466 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
484 real64 const (&invJ)[3][3],
508 real64 const (&invJ)[3][3],
531 real64 const (&invJ)[3][3],
619 real64 const (&X)[8][3] );
632 real64 const (&X)[4][3] );
661 template<
typename FUNC >
695 template<
typename FUNC >
729 template<
typename FUNC >
745 template<
typename FUNC >
763 template<
typename FUNC >
777 template<
typename FUNC >
791 template<
typename FUNC >
806 template<
typename FUNC >
811 FUNC && stiffnessVal );
826 real64 const ( &invJ )[3][3],
841 real64 const ( &invJ )[3][3],
847 constexpr
static real64 parentLength = GL_BASIS::parentSupportCoord( 1 ) - GL_BASIS::parentSupportCoord( 0 );
850 constexpr
static real64 parentVolume = parentLength*parentLength*parentLength;
860 template<
typename FUNC,
typename ... PARAMS >
863 static void supportLoop(
real64 const (&coords)[3],
865 PARAMS &&... params );
875 template<
typename FUNC,
typename ... PARAMS >
880 PARAMS &&... params );
887 template<
typename GL_BASIS >
888 template<
typename FUNC,
typename ... PARAMS >
894 PARAMS &&... params )
896 for(
int c=0; c<num1dNodes; ++c )
898 for(
int b=0; b<num1dNodes; ++b )
900 for(
int a=0; a<num1dNodes; ++a )
902 real64 const dNdXi[3] = { GL_BASIS::gradient( a, coords[0] )*
903 GL_BASIS::value( b, coords[1] )*
904 GL_BASIS::value( c, coords[2] ),
905 GL_BASIS::value( a, coords[0] )*
906 GL_BASIS::gradient( b, coords[1] )*
907 GL_BASIS::value( c, coords[2] ),
908 GL_BASIS::value( a, coords[0] )*
909 GL_BASIS::value( b, coords[1] )*
910 GL_BASIS::gradient( c, coords[2] )};
912 localIndex const nodeIndex = GL_BASIS::TensorProduct3D::linearIndex( a, b, c );
914 func( dNdXi, nodeIndex, std::forward< PARAMS >( params )... );
920 template<
typename GL_BASIS >
921 template<
typename FUNC,
typename ... PARAMS >
925 Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >::supportLoop(
localIndex const q,
927 PARAMS &&... params )
930 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
931 for(
int c=0; c<num1dNodes; ++c )
933 for(
int b=0; b<num1dNodes; ++b )
935 for(
int a=0; a<num1dNodes; ++a )
937 real64 const dNdXi[3] = { (b == qb && c == qc ) ? basisGradientAt( a, qa ) : 0,
938 (a == qa && c == qc ) ? basisGradientAt( b, qb ) : 0,
939 (a == qa && b == qb ) ? basisGradientAt( c, qc ) : 0 };
941 localIndex const nodeIndex = GL_BASIS::TensorProduct3D::linearIndex( a, b, c );
943 func( dNdXi, nodeIndex, std::forward< PARAMS >( params )... );
951 template<
typename GL_BASIS >
956 real64 const (&X)[numNodes][3],
957 real64 (& gradN)[numNodes][3] )
960 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
961 real64 Xmesh[8][3] = {{0}};
962 for(
int k = 0; k < 8; k++ )
964 const localIndex nodeIndex = meshIndexToLinearIndex3D( k );
965 for(
int i = 0; i < 3; i++ )
967 Xmesh[ k ][ i ] = X[ nodeIndex ][ i ];
972 jacobianTransformation( qa, qb, qc, Xmesh, J );
974 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
976 applyTransformationToParentGradients( q, J, gradN );
978 return detJ * GL_BASIS::weight( qa ) * GL_BASIS::weight( qb ) * GL_BASIS::weight( qc );
981 template<
typename GL_BASIS >
986 real64 const (&X)[numNodes][3],
989 for(
int i = 0; i < 3; ++i )
991 for(
int j = 0; j < 3; ++j )
997 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
998 real64 Xmesh[8][3] = {{0}};
999 for(
int k = 0; k < 8; k++ )
1001 const localIndex nodeIndex = meshIndexToLinearIndex3D( k );
1002 for(
int i = 0; i < 3; i++ )
1004 Xmesh[k][i] = X[nodeIndex][i];
1007 jacobianTransformation( qa, qb, qc, Xmesh, J );
1008 return LvArray::tensorOps::determinant< 3 >( J );
1011 template<
typename GL_BASIS >
1016 real64 const (&X)[numNodes][3],
1020 return calcJacobian( q, X, J );
1023 template<
typename GL_BASIS >
1028 real64 const (&X)[numNodes][3],
1029 real64 (& gradN)[numNodes][3] )
1033 jacobianTransformation( coords, X, J );
1035 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
1037 applyTransformationToParentGradients( coords, J, gradN );
1041 template<
typename GL_BASIS >
1046 real64 const (&X)[numNodes][3],
1048 real64 ( & gradN )[numNodes][3] )
1050 return calcGradN( q, X, gradN );
1053 template<
typename GL_BASIS >
1059 real64 (& gradN)[numNodes][3] )
1062 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1066 jacobianTransformation( qa, qb, qc, X, J );
1068 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
1070 applyTransformationToParentGradients( q, J, gradN );
1072 return detJ * GL_BASIS::weight( qa ) * GL_BASIS::weight( qb ) * GL_BASIS::weight( qc );
1075 template<
typename GL_BASIS >
1081 real64 (& gradN)[numNodes][3] )
1085 jacobianTransformationWithCorners( coords, X, J );
1087 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
1089 applyTransformationToParentGradients( coords, J, gradN );
1093 template<
typename GL_BASIS >
1100 real64 ( & gradN )[numNodes][3] )
1102 return calcGradN( q, X, gradN );
1106 #pragma GCC diagnostic push
1107 #pragma GCC diagnostic ignored "-Wshadow"
1110 template<
typename GL_BASIS >
1121 for(
int k = 0; k < 8; k++ )
1123 const int ka = k % 2;
1124 const int kb = ( k % 4 ) / 2;
1125 const int kc = k / 4;
1126 for(
int j = 0; j < 3; j++ )
1128 real64 jacCoeff = jacobianCoefficient1D( qa, 0, ka, j ) *
1129 jacobianCoefficient1D( qb, 1, kb, j ) *
1130 jacobianCoefficient1D( qc, 2, kc, j );
1131 for(
int i = 0; i < 3; i++ )
1133 J[i][j] += jacCoeff * X[k][i];
1139 template<
typename GL_BASIS >
1145 real64 const (&X)[numNodes][3],
1149 int const nodeIndex,
1150 real64 const (&X)[numNodes][3],
1154 for(
int i = 0; i < 3; ++i )
1156 for(
int j = 0; j < 3; ++j )
1158 J[i][j] = J[i][j] + dNdXi[ j ] * Xnode[i];
1164 template<
typename GL_BASIS >
1174 int const nodeIndex,
1179 GL_BASIS::TensorProduct3D::multiIndex( nodeIndex, qa, qb, qc );
1181 real64 alpha = ( GL_BASIS::parentSupportCoord( qa ) + 1.0 ) / 2.0;
1182 real64 beta = ( GL_BASIS::parentSupportCoord( qb ) + 1.0 ) / 2.0;
1183 real64 gamma = ( GL_BASIS::parentSupportCoord( qc ) + 1.0 ) / 2.0;
1184 trilinearInterp( alpha, beta, gamma, X, Xnode );
1185 for(
int i = 0; i < 3; ++i )
1187 for(
int j = 0; j < 3; ++j )
1189 J[i][j] = J[i][j] + dNdXi[ j ] * Xnode[i];
1195 template<
typename GL_BASIS >
1206 for(
int i=0; i<3; i++ )
1208 coords[i] = X[0][i]*( 1.0-alpha )*( 1.0-beta )*( 1.0-gamma )+
1209 X[1][i]* alpha *( 1.0-beta )*( 1.0-gamma )+
1210 X[2][i]*( 1.0-alpha )* beta *( 1.0-gamma )+
1211 X[3][i]* alpha * beta *( 1.0-gamma )+
1212 X[4][i]*( 1.0-alpha )*( 1.0-beta )* gamma+
1213 X[5][i]* alpha *( 1.0-beta )* gamma+
1214 X[6][i]*( 1.0-alpha )* beta * gamma+
1215 X[7][i]* alpha * beta * gamma;
1220 template<
typename GL_BASIS >
1226 real64 const (&X)[numNodes][3] )
1229 for(
int q=0; q<numNodes; q++ )
1231 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1232 real64 alpha = ( GL_BASIS::parentSupportCoord( qa ) + 1.0 ) / 2.0;
1233 real64 beta = ( GL_BASIS::parentSupportCoord( qb ) + 1.0 ) / 2.0;
1234 real64 gamma = ( GL_BASIS::parentSupportCoord( qc ) + 1.0 ) / 2.0;
1235 trilinearInterp( alpha, beta, gamma, Xmesh, X[q] );
1239 template<
typename GL_BASIS >
1249 for(
int k = 0; k < 4; k++ )
1253 for(
int j = 0; j < 2; j++ )
1255 real64 jacCoeff = jacobianCoefficient1D( qa, 0, ka, j ) *
1256 jacobianCoefficient1D( qb, 1, kb, j );
1257 for(
int i = 0; i < 3; i++ )
1259 J[i][j] += jacCoeff * X[k][i];
1265 template<
typename GL_BASIS >
1271 real64 const (&X)[8][3] )
1274 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1275 const real64 w3D = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1277 jacobianTransformation( qa, qb, qc, X, J );
1278 return LvArray::math::abs( LvArray::tensorOps::determinant< 3 >( J ) )*w3D;
1281 template<
typename GL_BASIS >
1287 real64 const (&X)[4][3] )
1290 GL_BASIS::TensorProduct2D::multiIndex( q, qa, qb );
1291 const real64 w2D = GL_BASIS::weight( qa )*GL_BASIS::weight( qb );
1294 jacobianTransformation2d( qa, qb, X, J );
1296 B[0] = J[0][0]*J[0][0]+J[1][0]*J[1][0]+J[2][0]*J[2][0];
1297 B[1] = J[0][1]*J[0][1]+J[1][1]*J[1][1]+J[2][1]*J[2][1];
1298 B[2] = J[0][0]*J[0][1]+J[1][0]*J[1][1]+J[2][0]*J[2][1];
1299 return sqrt( LvArray::math::abs( LvArray::tensorOps::symDeterminant< 2 >( B ) ) )*w2D;
1302 template<
typename GL_BASIS >
1314 jacobianTransformation( qa, qb, qc, X, J );
1315 real64 const detJ = LvArray::tensorOps::determinant< 3 >( J );
1318 B[0] = (J[0][0]*J[0][0]+J[1][0]*J[1][0]+J[2][0]*J[2][0])/detJ;
1319 B[1] = (J[0][1]*J[0][1]+J[1][1]*J[1][1]+J[2][1]*J[2][1])/detJ;
1320 B[2] = (J[0][2]*J[0][2]+J[1][2]*J[1][2]+J[2][2]*J[2][2])/detJ;
1321 B[3] = (J[0][1]*J[0][2]+J[1][1]*J[1][2]+J[2][1]*J[2][2])/detJ;
1322 B[4] = (J[0][0]*J[0][2]+J[1][0]*J[1][2]+J[2][0]*J[2][2])/detJ;
1323 B[5] = (J[0][0]*J[0][1]+J[1][0]*J[1][1]+J[2][0]*J[2][1])/detJ;
1326 LvArray::tensorOps::symInvert< 3 >( B );
1329 template<
typename GL_BASIS >
1341 jacobianTransformation( qa, qb, qc, X, J );
1342 real64 const detJ = LvArray::tensorOps::determinant< 3 >( J );
1344 real64 Jinv[3][3] = {{0}};
1345 LvArray::tensorOps::invert< 3 >( Jinv, J );
1348 B[0] = detJ*(Jinv[0][2]*Jinv[0][2]);
1349 B[1] = detJ*(Jinv[1][2]*Jinv[1][2]);
1350 B[2] = detJ*(Jinv[2][2]*Jinv[2][2]);
1351 B[3] = detJ*(Jinv[1][2]*Jinv[2][2]);
1352 B[4] = detJ*(Jinv[0][2]*Jinv[2][2]);
1353 B[5] = detJ*(Jinv[0][2]*Jinv[1][2]);
1356 template<
typename GL_BASIS >
1368 jacobianTransformation( qa, qb, qc, X, J );
1369 real64 const detJ = LvArray::tensorOps::determinant< 3 >( J );
1371 real64 Jinv[3][3] = {{0}};
1372 LvArray::tensorOps::invert< 3 >( Jinv, J );
1375 B[0] = detJ*(Jinv[0][0]*Jinv[0][0] + Jinv[0][1]*Jinv[0][1]);
1376 B[1] = detJ*(Jinv[1][1]*Jinv[1][1] + Jinv[1][0]*Jinv[1][0]);
1377 B[2] = detJ*(Jinv[2][0]*Jinv[2][0] + Jinv[2][1]*Jinv[2][1]);
1378 B[3] = detJ*(Jinv[1][0]*Jinv[2][0] + Jinv[1][1]*Jinv[2][1]);
1379 B[4] = detJ*(Jinv[0][0]*Jinv[2][0] + Jinv[0][1]*Jinv[2][1]);
1380 B[5] = detJ*(Jinv[0][0]*Jinv[1][0] + Jinv[0][1]*Jinv[1][1]);
1383 template<
typename GL_BASIS >
1384 template<
typename FUNC >
1395 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1396 for(
int i=0; i<num1dNodes; i++ )
1398 const int ibc = GL_BASIS::TensorProduct3D::linearIndex( i, qb, qc );
1399 const int aic = GL_BASIS::TensorProduct3D::linearIndex( qa, i, qc );
1400 const int abi = GL_BASIS::TensorProduct3D::linearIndex( qa, qb, i );
1401 const real64 gia = basisGradientAt( i, qa );
1402 const real64 gib = basisGradientAt( i, qb );
1403 const real64 gic = basisGradientAt( i, qc );
1404 for(
int j=0; j<num1dNodes; j++ )
1406 const int jbc = GL_BASIS::TensorProduct3D::linearIndex( j, qb, qc );
1407 const int ajc = GL_BASIS::TensorProduct3D::linearIndex( qa, j, qc );
1408 const int abj = GL_BASIS::TensorProduct3D::linearIndex( qa, qb, j );
1409 const real64 gja = basisGradientAt( j, qa );
1410 const real64 gjb = basisGradientAt( j, qb );
1411 const real64 gjc = basisGradientAt( j, qc );
1413 const real64 w0 = w * gia * gja;
1414 func( ibc, jbc, w0 * B[0] );
1415 const real64 w1 = w * gib * gjb;
1416 func( aic, ajc, w1 * B[1] );
1417 const real64 w2 = w * gic * gjc;
1418 func( abi, abj, w2 * B[2] );
1420 const real64 w3 = w * gib * gjc;
1421 func( aic, abj, w3 * B[3] );
1422 func( abj, aic, w3 * B[3] );
1423 const real64 w4 = w * gia * gjc;
1424 func( ibc, abj, w4 * B[4] );
1425 func( abj, ibc, w4 * B[4] );
1426 const real64 w5 = w * gia * gjb;
1427 func( ibc, ajc, w5 * B[5] );
1428 func( ajc, ibc, w5 * B[5] );
1433 template<
typename GL_BASIS >
1434 template<
typename FUNC >
1444 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1447 computeBxyMatrix( qa, qb, qc, X, J, B );
1448 computeGradPhiBGradPhi( qa, qb, qc, B, func );
1451 template<
typename GL_BASIS >
1452 template<
typename FUNC >
1462 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1465 computeBzMatrix( qa, qb, qc, X, J, B );
1466 computeGradPhiBGradPhi( qa, qb, qc, B, func );
1469 template<
typename GL_BASIS >
1470 template<
typename FUNC >
1480 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1483 computeBMatrix( qa, qb, qc, X, J, B );
1484 computeGradPhiBGradPhi( qa, qb, qc, B, func );
1487 template<
typename GL_BASIS >
1488 template<
typename FUNC >
1498 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1500 jacobianTransformation( qa, qb, qc, X, J );
1501 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
1502 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1503 for(
int i=0; i<num1dNodes; i++ )
1505 const int ibc = GL_BASIS::TensorProduct3D::linearIndex( i, qb, qc );
1506 const int aic = GL_BASIS::TensorProduct3D::linearIndex( qa, i, qc );
1507 const int abi = GL_BASIS::TensorProduct3D::linearIndex( qa, qb, i );
1508 const real64 gia = basisGradientAt( i, qa );
1509 const real64 gib = basisGradientAt( i, qb );
1510 const real64 gic = basisGradientAt( i, qc );
1511 for(
int j=0; j<num1dNodes; j++ )
1513 const int jbc = GL_BASIS::TensorProduct3D::linearIndex( j, qb, qc );
1514 const int ajc = GL_BASIS::TensorProduct3D::linearIndex( qa, j, qc );
1515 const int abj = GL_BASIS::TensorProduct3D::linearIndex( qa, qb, j );
1516 const real64 gja = basisGradientAt( j, qa );
1517 const real64 gjb = basisGradientAt( j, qb );
1518 const real64 gjc = basisGradientAt( j, qc );
1520 const real64 w00 = w * gia * gja;
1521 func( ibc, jbc, w00 * detJ, J, 0, 0 );
1522 const real64 w11 = w * gib * gjb;
1523 func( aic, ajc, w11 * detJ, J, 1, 1 );
1524 const real64 w22 = w * gic * gjc;
1525 func( abi, abj, w22 * detJ, J, 2, 2 );
1527 const real64 w12 = w * gib * gjc;
1528 func( aic, abj, w12 * detJ, J, 1, 2 );
1529 func( abj, aic, w12 * detJ, J, 2, 1 );
1530 const real64 w02 = w * gia * gjc;
1531 func( ibc, abj, w02 * detJ, J, 0, 2 );
1532 func( abj, ibc, w02 * detJ, J, 2, 0 );
1533 const real64 w01 = w * gia * gjb;
1534 func( ibc, ajc, w01 * detJ, J, 0, 1 );
1535 func( ajc, ibc, w01 * detJ, J, 1, 0 );
1540 template<
typename GL_BASIS >
1541 template<
typename FUNC >
1551 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1553 jacobianTransformation( qa, qb, qc, X, J );
1554 const real64 detJ = LvArray::tensorOps::invert< 3 >( J );
1555 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1557 for(
int i1 = 0; i1 < num1dNodes; ++i1 )
1559 auto val = w * basisGradientAt( i1, qa );
1560 func( GL_BASIS::TensorProduct3D::linearIndex( i1, qb, qc ), q, detJ*J[0][0]*val, detJ*J[0][1]*val, detJ*J[0][2]*val );
1565 template<
typename GL_BASIS >
1566 template<
typename FUNC >
1576 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1578 jacobianTransformation( qa, qb, qc, X, J );
1579 const real64 detJ = LvArray::tensorOps::invert< 3 >( J );
1580 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1582 for(
int i2 = 0; i2 < num1dNodes; ++i2 )
1584 auto val = w * basisGradientAt( i2, qb );
1585 func( GL_BASIS::TensorProduct3D::linearIndex( qa, i2, qc ), q, detJ*J[1][0]*val, detJ*J[1][1]*val, detJ*J[1][2]*val );
1589 template<
typename GL_BASIS >
1590 template<
typename FUNC >
1600 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1602 jacobianTransformation( qa, qb, qc, X, J );
1603 const real64 detJ = LvArray::tensorOps::invert< 3 >( J );
1604 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1606 for(
int i3 = 0; i3 < num1dNodes; ++i3 )
1608 auto val = w * basisGradientAt( i3, qc );
1609 func( GL_BASIS::TensorProduct3D::linearIndex( qa, qb, i3 ), q, detJ*J[2][0]*val, detJ*J[2][1]*val, detJ*J[2][2]*val );
1614 template<
typename GL_BASIS >
1620 real64 const ( &invJ )[3][3],
1621 real64 (& gradN)[numNodes][3] )
1624 int const nodeIndex,
1625 real64 const (&invJ)[3][3],
1626 real64 (& gradN)[numNodes][3] )
1629 gradN[nodeIndex][0] = dNdXi[0] * invJ[0][0] + dNdXi[1] * invJ[1][0] + dNdXi[2] * invJ[2][0];
1630 gradN[nodeIndex][1] = dNdXi[0] * invJ[0][1] + dNdXi[1] * invJ[1][1] + dNdXi[2] * invJ[2][1];
1631 gradN[nodeIndex][2] = dNdXi[0] * invJ[0][2] + dNdXi[1] * invJ[1][2] + dNdXi[2] * invJ[2][2];
1638 template<
typename GL_BASIS >
1644 real64 const ( &invJ )[3][3],
1645 real64 (& gradN)[numNodes][3] )
1648 int const nodeIndex,
1649 real64 const (&invJ)[3][3],
1650 real64 (& gradN)[numNodes][3] )
1652 gradN[nodeIndex][0] = dNdXi[0] * invJ[0][0] + dNdXi[1] * invJ[1][0] + dNdXi[2] * invJ[2][0];
1653 gradN[nodeIndex][1] = dNdXi[0] * invJ[0][1] + dNdXi[1] * invJ[1][1] + dNdXi[2] * invJ[2][1];
1654 gradN[nodeIndex][2] = dNdXi[0] * invJ[0][2] + dNdXi[1] * invJ[1][2] + dNdXi[2] * invJ[2][2];
1658 template<
typename GL_BASIS >
1664 real64 const (&X)[numNodes][3] )
1667 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1670 jacobianTransformation( qa, qb, qc, X, J );
1672 return LvArray::tensorOps::determinant< 3 >( J );
1677 template<
typename GL_BASIS >
1682 real64 const (&invJ)[3][3],
1683 real64 const (&var)[numNodes][3],
1687 int const nodeIndex,
1688 real64 const (&invJ)[3][3],
1689 real64 const (&var)[numNodes][3],
1693 real64 gradN[3] = {0, 0, 0};
1694 for(
int i = 0; i < 3; ++i )
1696 for(
int j = 0; j < 3; ++j )
1698 gradN[i] = gradN[i] + dNdXi[ j ] * invJ[j][i];
1702 grad[0] = grad[0] + gradN[0] * var[ nodeIndex ][0];
1703 grad[1] = grad[1] + gradN[1] * var[ nodeIndex ][1];
1704 grad[2] = grad[2] + gradN[2] * var[ nodeIndex ][2];
1705 grad[3] = grad[3] + gradN[2] * var[ nodeIndex ][1] + gradN[1] * var[ nodeIndex ][2];
1706 grad[4] = grad[4] + gradN[2] * var[ nodeIndex ][0] + gradN[0] * var[ nodeIndex ][2];
1707 grad[5] = grad[5] + gradN[1] * var[ nodeIndex ][0] + gradN[0] * var[ nodeIndex ][1];
1708 }, invJ, var, grad );
1711 template<
typename GL_BASIS >
1716 real64 const (&invJ)[3][3],
1718 real64 (& R)[numNodes][3] )
1722 (
real64 const (&dNdXi)[3],
1723 int const nodeIndex,
1724 real64 const (&invJ)[3][3],
1726 real64 (& R)[numNodes][3] )
1729 real64 gradN[3] = {0, 0, 0};
1730 for(
int i = 0; i < 3; ++i )
1732 for(
int j = 0; j < 3; ++j )
1734 gradN[i] = gradN[i] + dNdXi[ j ] * invJ[j][i];
1737 R[ nodeIndex ][ 0 ] = R[ nodeIndex ][ 0 ] - var[ 0 ] * gradN[ 0 ] - var[ 5 ] * gradN[ 1 ] - var[ 4 ] * gradN[ 2 ];
1738 R[ nodeIndex ][ 1 ] = R[ nodeIndex ][ 1 ] - var[ 5 ] * gradN[ 0 ] - var[ 1 ] * gradN[ 1 ] - var[ 3 ] * gradN[ 2 ];
1739 R[ nodeIndex ][ 2 ] = R[ nodeIndex ][ 2 ] - var[ 4 ] * gradN[ 0 ] - var[ 3 ] * gradN[ 1 ] - var[ 2 ] * gradN[ 2 ];
1745 template<
typename GL_BASIS >
1750 real64 const (&invJ)[3][3],
1751 real64 const (&var)[numNodes][3],
1755 int const nodeIndex,
1756 real64 const (&invJ)[3][3],
1757 real64 const (&var)[numNodes][3],
1760 for(
int i = 0; i < 3; ++i )
1763 for(
int j = 0; j < 3; ++j )
1765 gradN = gradN + dNdXi[ j ] * invJ[j][i];
1767 for(
int k = 0; k < 3; ++k )
1769 grad[k][i] = grad[k][i] + gradN * var[ nodeIndex ][k];
1772 }, invJ, var, grad );
1776 template<
typename GL_BASIS >
1777 class Qk_Hexahedron_Lagrange_GaussLobatto final :
public Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >,
1778 public FiniteElementBase
1783 using BASIS = GL_BASIS;
1785 using ImplType = Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS >;
1787 Qk_Hexahedron_Lagrange_GaussLobatto(): FiniteElementBase( ImplType::numNodes,
1788 ImplType::maxSupportPoints,
1789 ImplType::numQuadraturePoints )
1796 Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS > * getImpl()
1798 return static_cast< Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS > *
>(
this);
1805 const Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS > * getImpl()
const
1807 return static_cast< const Qk_Hexahedron_Lagrange_GaussLobatto_impl< GL_BASIS > *
>(
this);
1810 virtual ~Qk_Hexahedron_Lagrange_GaussLobatto() override final = default;
1840 using Q1_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis1 >;
1883 using Q2_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis2 >;
1927 using Q3_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis3GL >;
1965 using Q4_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis4GL >;
2017 using Q5_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis5GL >;
2019 using Q1_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis1 >;
2020 using Q2_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis2 >;
2021 using Q3_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis3GL >;
2022 using Q4_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis4GL >;
2023 using Q5_Hexahedron_Lagrange_GaussLobatto_impl = Qk_Hexahedron_Lagrange_GaussLobatto_impl< LagrangeBasis5GL >;
2028 #pragma GCC diagnostic pop
2030 #undef PARENT_GRADIENT_METHOD
#define GEOS_HOST_DEVICE
Marks a host-device function.
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
#define GEOS_FORCE_INLINE
Marks a function or lambda for inlining.
#define GEOS_RESTRICT
preprocessor variable for the C99 restrict keyword for use with pointers
#define GEOS_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
Device-compatible (non virtual) Base class for all finite element formulations.
constexpr static localIndex numQuadraturePoints
The number of quadrature points per element.
constexpr static localIndex maxSupportPoints
The maximum number of support points per element.
constexpr static localIndex numNodes
The number of nodes per element.
GEOS_HOST_DEVICE FiniteElementBase_impl & operator=(FiniteElementBase_impl const &)=default
Default copy assignment operator.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 computeDampingTerm(localIndex const q, real64 const (&X)[4][3])
computes the non-zero contributions of the d.o.f. indexd by q to the damping matrix M,...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeBMatrix(int const qa, int const qb, int const qc, real64 const (&X)[8][3], real64(&J)[3][3], real64(&B)[6])
computes the matrix B, defined as J^{-T}J^{-1}/det(J), where J is the Jacobian matrix,...
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE real64 jacobianCoefficient1D(const int q, const int i, const int k, const int dir)
Compute the 1D factor of the coefficient of the jacobian on the q-th quadrature point,...
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE localIndex linearIndex2DVal(const localIndex qa, const localIndex qb)
The linear index associated to the given one-dimensional indices in the two directions.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeBzMatrix(int const qa, int const qb, int const qc, real64 const (&X)[8][3], real64(&J)[3][3], real64(&B)[6])
computes the matrix B in the case of quasi-stiffness (e.g. for pseudo-acoustic case),...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 computeMassTerm(localIndex const q, real64 const (&X)[8][3])
computes the non-zero contributions of the d.o.f. indexd by q to the mass matrix M,...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void calcN(localIndex const q, real64(&N)[numNodes])
Calculate shape functions values for each support point at a quadrature point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 transformedQuadratureWeight(localIndex const q, real64 const (&X)[numNodes][3])
Calculate the integration weights for a quadrature point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeLocalCoords(real64 const (&Xmesh)[8][3], real64 const (&X)[numNodes][3])
computes the real-world coordinates of the support nodes
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeStiffnessxyTerm(localIndex const q, real64 const (&X)[8][3], FUNC &&func)
computes the non-zero contributions of the d.o.f. indexed by q to the partial-stiffness matrix R,...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 calcGradNWithCorners(localIndex const q, real64 const (&X)[8][3], real64(&gradN)[numNodes][3])
Calculate the shape functions derivatives wrt the physical coordinates.
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE localIndex meshIndexToLinearIndex2D(localIndex const k)
Converts from the index of the point in the mesh and the linear 2D index of the corresponding dof.
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE real64 interpolationCoord(const int q, const int k)
Compute the interpolation coefficients of the q-th quadrature point in a given direction.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeStiffnessTerm(localIndex const q, real64 const (&X)[8][3], FUNC &&func)
computes the non-zero contributions of the d.o.f. indexed by q to the stiffness matrix R,...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void calcN(real64 const (&coords)[3], real64(&N)[numNodes])
Calculate shape functions values at a single point.
constexpr static localIndex halfNodes
Half the number of support points, rounded down. Precomputed for efficiency.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE localIndex getNumQuadraturePoints(StackVariables const &stack)
Get the number of quadrature points.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 calcGradN(localIndex const q, real64 const (&X)[numNodes][3], real64(&gradN)[numNodes][3])
Calculate the shape functions derivatives wrt the physical coordinates.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeGradPhiBGradPhi(int const qa, int const qb, int const qc, real64 const (&B)[6], FUNC &&func)
Computes the "Grad(Phi)*B*Grad(Phi)" coefficient of the stiffness term. The matrix B must be provided...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 calcGradNWithCorners(localIndex const q, real64 const (&X)[8][3], StackVariables const &stack, real64(&gradN)[numNodes][3])
Calculate the shape functions derivatives wrt the physical coordinates.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 calcJacobian(localIndex const q, real64 const (&X)[numNodes][3], StackVariables const &stack, real64(&J)[3][3])
Calculate the Jacobian matrix at a quadrature point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeFirstOrderStiffnessTermZ(localIndex const q, real64 const (&X)[8][3], FUNC &&func)
computes the non-zero contributions of the d.o.f. indexd by q to the z-part of the first order stiffn...
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE localIndex meshIndexToLinearIndex3D(localIndex const k)
Converts from the index of the point in the mesh and the linear 3D index of the corresponding dof.
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE real64 basisGradientAt(const int q, const int p)
Compute the 1st derivative of the q-th 1D basis function at quadrature point p.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 calcJacobian(localIndex const q, real64 const (&X)[numNodes][3], real64(&J)[3][3])
Calculate the Jacobian matrix at a quadrature point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void trilinearInterp(real64 const alpha, real64 const beta, real64 const gamma, real64 const (&X)[8][3], real64(&coords)[3])
performs a trilinear interpolation to determine the real-world coordinates of a vertex
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void jacobianTransformation2d(int const qa, int const qb, real64 const (&X)[4][3], real64(&J)[3][2])
Calculates the isoparametric "Jacobian" transformation matrix/mapping from the parent space to the ph...
constexpr static localIndex numNodesPerFace
The number of nodes/support points per face.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeFirstOrderStiffnessTermX(localIndex const q, real64 const (&X)[8][3], FUNC &&func)
computes the non-zero contributions of the d.o.f. indexd by q to the x-part of the first order stiffn...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeFirstOrderStiffnessTerm(localIndex const q, real64 const (&X)[8][3], FUNC &&stiffnessVal)
computes the non-zero contributions of the d.o.f. indexd by q to the stiffness matrix R for the elast...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void applyTransformationToParentGradients(int const q, real64 const (&invJ)[3][3], real64(&gradN)[numNodes][3])
Apply a Jacobian transformation matrix from the parent space to the physical space on the parent shap...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void calcN(localIndex const q, StackVariables const &stack, real64(&N)[numNodes])
Calculate shape functions values for each support point at a quadrature point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void jacobianTransformation(int const qa, int const qb, int const qc, real64 const (&X)[8][3], real64(&J)[3][3])
Calculates the isoparametric "Jacobian" transformation matrix/mapping from the parent space to the ph...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 invJacobianTransformation(int const qa, int const qb, int const qc, real64 const (&X)[8][3], real64(&J)[3][3])
Calculates the isoparametric "Jacobian" transformation matrix/mapping from the parent space to the ph...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void jacobianTransformationWithCorners(real64 const (&coords)[3], real64 const (&X)[8][3], real64(&J)[3][3])
Calculates the isoparametric "Jacobian" transformation matrix/mapping from the parent space to the ph...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void applyTransformationToParentGradients(real64 const (&coords)[3], real64 const (&invJ)[3][3], real64(&gradN)[numNodes][3])
Apply a Jacobian transformation matrix from the parent space to the physical space on the parent shap...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 invJacobianTransformation(int const q, real64 const (&X)[8][3], real64(&J)[3][3])
Calculates the isoparametric "Jacobian" transformation matrix/mapping from the parent space to the ph...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void plusGradNajAij(int const q, real64 const (&invJ)[3][3], real64 const (&var)[6], real64(&R)[numNodes][3])
Inner product of all basis function gradients and a rank-2 symmetric tensor evaluated at a quadrature...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeBxyMatrix(int const qa, int const qb, int const qc, real64 const (&X)[8][3], real64(&J)[3][3], real64(&B)[6])
computes the matrix B in the case of quasi-stiffness (e.g. for pseudo-acoustic case),...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void symmetricGradient(int const q, real64 const (&invJ)[3][3], real64 const (&var)[numNodes][3], real64(&grad)[6])
Calculate the symmetric gradient of a vector valued support field at a quadrature point using the sto...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeStiffnesszTerm(localIndex const q, real64 const (&X)[8][3], FUNC &&func)
computes the non-zero contributions of the d.o.f. indexed by q to the partial-stiffness matrix R,...
constexpr static localIndex num1dNodes
The number of nodes/support points per element per dimension.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void jacobianTransformation(real64 const (&coords)[3], real64 const (&X)[numNodes][3], real64(&J)[3][3])
Calculates the isoparametric "Jacobian" transformation matrix/mapping from the parent space to the ph...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 calcGradN(localIndex const q, real64 const (&X)[numNodes][3], StackVariables const &stack, real64(&gradN)[numNodes][3])
Calculate the shape functions derivatives wrt the physical coordinates.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 calcGradN(real64 const (&coords)[3], real64 const (&X)[numNodes][3], real64(&gradN)[numNodes][3])
Calculate the shape functions derivatives wrt the physical coordinates at a single point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeFirstOrderStiffnessTermY(localIndex const q, real64 const (&X)[8][3], FUNC &&func)
computes the non-zero contributions of the d.o.f. indexd by q to the y-part of the first order stiffn...
DO_NOT_DOCUMENT GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE localIndex linearIndex3DVal(const localIndex qa, localIndex const qb, localIndex const qc)
The linear index associated to the given one-dimensional indices in the three directions.
typename Base::template MeshData< SubregionType > MeshData
Mesh data structure for the element.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 calcGradNWithCorners(real64 const (&coords)[3], real64 const (&X)[8][3], real64(&gradN)[numNodes][3])
Calculate the shape functions derivatives wrt the physical coordinates at a single point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void gradient(int const q, real64 const (&invJ)[3][3], real64 const (&var)[numNodes][3], real64(&grad)[3][3])
Calculate the gradient of a vector valued support field at a point using the stored basis function gr...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE localIndex getNumSupportPoints(StackVariables const &stack)
Get the number of support points.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Kernel variables (dof numbers, jacobian and residual) located on the stack.