20 #ifndef GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_Q1HEXAHEDRON_HPP_
21 #define GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_Q1HEXAHEDRON_HPP_
43 template<
typename GL_BASIS >
184 GL_BASIS::TensorProduct3D::value( coords, N );
197 const real64 alpha = ( GL_BASIS::parentSupportCoord( q ) + 1.0 ) / 2.0;
198 return k == 0 ? ( 1.0 - alpha ) : alpha;
214 return GL_BASIS::gradientAt( q, p );
218 return -GL_BASIS::gradientAt( GL_BASIS::numSupportPoints - 1 - q, GL_BASIS::numSupportPoints - 1 - p );
239 return k== 0 ? -1.0/2.0 : 1.0/2.0;
281 return calcN( q, N );
423 return LvArray::tensorOps::invert< 3 >( J );
441 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
459 real64 const (&invJ)[3][3],
483 real64 const (&invJ)[3][3],
506 real64 const (&invJ)[3][3],
594 real64 const (&X)[8][3] );
607 real64 const (&X)[4][3] );
636 template<
typename FUNC >
670 template<
typename FUNC >
704 template<
typename FUNC >
720 template<
typename FUNC >
738 template<
typename FUNC >
752 template<
typename FUNC >
766 template<
typename FUNC >
781 template<
typename FUNC >
786 FUNC && stiffnessVal );
801 real64 const ( &invJ )[3][3],
816 real64 const ( &invJ )[3][3],
822 constexpr
static real64 parentLength = GL_BASIS::parentSupportCoord( 1 ) - GL_BASIS::parentSupportCoord( 0 );
825 constexpr
static real64 parentVolume = parentLength*parentLength*parentLength;
835 template<
typename FUNC,
typename ... PARAMS >
838 static void supportLoop(
real64 const (&coords)[3],
840 PARAMS &&... params );
850 template<
typename FUNC,
typename ... PARAMS >
855 PARAMS &&... params );
862 template<
typename GL_BASIS >
863 template<
typename FUNC,
typename ... PARAMS >
869 PARAMS &&... params )
871 for(
int c=0; c<num1dNodes; ++c )
873 for(
int b=0; b<num1dNodes; ++b )
875 for(
int a=0; a<num1dNodes; ++a )
877 real64 const dNdXi[3] = { GL_BASIS::gradient( a, coords[0] )*
878 GL_BASIS::value( b, coords[1] )*
879 GL_BASIS::value( c, coords[2] ),
880 GL_BASIS::value( a, coords[0] )*
881 GL_BASIS::gradient( b, coords[1] )*
882 GL_BASIS::value( c, coords[2] ),
883 GL_BASIS::value( a, coords[0] )*
884 GL_BASIS::value( b, coords[1] )*
885 GL_BASIS::gradient( c, coords[2] )};
887 localIndex const nodeIndex = GL_BASIS::TensorProduct3D::linearIndex( a, b, c );
889 func( dNdXi, nodeIndex, std::forward< PARAMS >( params )... );
895 template<
typename GL_BASIS >
896 template<
typename FUNC,
typename ... PARAMS >
900 Qk_Hexahedron_Lagrange_GaussLobatto< GL_BASIS >::supportLoop(
localIndex const q,
902 PARAMS &&... params )
905 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
906 for(
int c=0; c<num1dNodes; ++c )
908 for(
int b=0; b<num1dNodes; ++b )
910 for(
int a=0; a<num1dNodes; ++a )
912 real64 const dNdXi[3] = { (b == qb && c == qc ) ? basisGradientAt( a, qa ) : 0,
913 (a == qa && c == qc ) ? basisGradientAt( b, qb ) : 0,
914 (a == qa && b == qb ) ? basisGradientAt( c, qc ) : 0 };
916 localIndex const nodeIndex = GL_BASIS::TensorProduct3D::linearIndex( a, b, c );
918 func( dNdXi, nodeIndex, std::forward< PARAMS >( params )... );
926 template<
typename GL_BASIS >
931 real64 const (&X)[numNodes][3],
932 real64 (& gradN)[numNodes][3] )
935 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
936 real64 Xmesh[8][3] = {{0}};
937 for(
int k = 0; k < 8; k++ )
939 const localIndex nodeIndex = meshIndexToLinearIndex3D( k );
940 for(
int i = 0; i < 3; i++ )
942 Xmesh[ k ][ i ] = X[ nodeIndex ][ i ];
947 jacobianTransformation( qa, qb, qc, Xmesh, J );
949 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
951 applyTransformationToParentGradients( q, J, gradN );
956 template<
typename GL_BASIS >
961 real64 const (&X)[numNodes][3],
962 real64 (& gradN)[numNodes][3] )
966 jacobianTransformation( coords, X, J );
968 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
970 applyTransformationToParentGradients( coords, J, gradN );
974 template<
typename GL_BASIS >
979 real64 const (&X)[numNodes][3],
981 real64 ( & gradN )[numNodes][3] )
983 return calcGradN( q, X, gradN );
986 template<
typename GL_BASIS >
992 real64 (& gradN)[numNodes][3] )
995 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
999 jacobianTransformation( qa, qb, qc, X, J );
1001 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
1003 applyTransformationToParentGradients( q, J, gradN );
1008 template<
typename GL_BASIS >
1014 real64 (& gradN)[numNodes][3] )
1018 jacobianTransformationWithCorners( coords, X, J );
1020 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
1022 applyTransformationToParentGradients( coords, J, gradN );
1026 template<
typename GL_BASIS >
1033 real64 ( & gradN )[numNodes][3] )
1035 return calcGradN( q, X, gradN );
1039 #pragma GCC diagnostic push
1040 #pragma GCC diagnostic ignored "-Wshadow"
1043 template<
typename GL_BASIS >
1054 for(
int k = 0; k < 8; k++ )
1056 const int ka = k % 2;
1057 const int kb = ( k % 4 ) / 2;
1058 const int kc = k / 4;
1059 for(
int j = 0; j < 3; j++ )
1061 real64 jacCoeff = jacobianCoefficient1D( qa, 0, ka, j ) *
1062 jacobianCoefficient1D( qb, 1, kb, j ) *
1063 jacobianCoefficient1D( qc, 2, kc, j );
1064 for(
int i = 0; i < 3; i++ )
1066 J[i][j] += jacCoeff * X[k][i];
1072 template<
typename GL_BASIS >
1078 real64 const (&X)[numNodes][3],
1082 int const nodeIndex,
1083 real64 const (&X)[numNodes][3],
1087 for(
int i = 0; i < 3; ++i )
1089 for(
int j = 0; j < 3; ++j )
1091 J[i][j] = J[i][j] + dNdXi[ j ] * Xnode[i];
1097 template<
typename GL_BASIS >
1107 int const nodeIndex,
1112 GL_BASIS::TensorProduct3D::multiIndex( nodeIndex, qa, qb, qc );
1114 real64 alpha = ( GL_BASIS::parentSupportCoord( qa ) + 1.0 ) / 2.0;
1115 real64 beta = ( GL_BASIS::parentSupportCoord( qb ) + 1.0 ) / 2.0;
1116 real64 gamma = ( GL_BASIS::parentSupportCoord( qc ) + 1.0 ) / 2.0;
1117 trilinearInterp( alpha, beta, gamma, X, Xnode );
1118 for(
int i = 0; i < 3; ++i )
1120 for(
int j = 0; j < 3; ++j )
1122 J[i][j] = J[i][j] + dNdXi[ j ] * Xnode[i];
1128 template<
typename GL_BASIS >
1139 for(
int i=0; i<3; i++ )
1141 coords[i] = X[0][i]*( 1.0-alpha )*( 1.0-beta )*( 1.0-gamma )+
1142 X[1][i]* alpha *( 1.0-beta )*( 1.0-gamma )+
1143 X[2][i]*( 1.0-alpha )* beta *( 1.0-gamma )+
1144 X[3][i]* alpha * beta *( 1.0-gamma )+
1145 X[4][i]*( 1.0-alpha )*( 1.0-beta )* gamma+
1146 X[5][i]* alpha *( 1.0-beta )* gamma+
1147 X[6][i]*( 1.0-alpha )* beta * gamma+
1148 X[7][i]* alpha * beta * gamma;
1153 template<
typename GL_BASIS >
1159 real64 const (&X)[numNodes][3] )
1162 for(
int q=0; q<numNodes; q++ )
1164 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1165 real64 alpha = ( GL_BASIS::parentSupportCoord( qa ) + 1.0 ) / 2.0;
1166 real64 beta = ( GL_BASIS::parentSupportCoord( qb ) + 1.0 ) / 2.0;
1167 real64 gamma = ( GL_BASIS::parentSupportCoord( qc ) + 1.0 ) / 2.0;
1168 trilinearInterp( alpha, beta, gamma, Xmesh, X[q] );
1172 template<
typename GL_BASIS >
1182 for(
int k = 0; k < 4; k++ )
1186 for(
int j = 0; j < 2; j++ )
1188 real64 jacCoeff = jacobianCoefficient1D( qa, 0, ka, j ) *
1189 jacobianCoefficient1D( qb, 1, kb, j );
1190 for(
int i = 0; i < 3; i++ )
1192 J[i][j] += jacCoeff * X[k][i];
1198 template<
typename GL_BASIS >
1204 real64 const (&X)[8][3] )
1207 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1208 const real64 w3D = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1210 jacobianTransformation( qa, qb, qc, X, J );
1211 return LvArray::math::abs( LvArray::tensorOps::determinant< 3 >( J ) )*w3D;
1214 template<
typename GL_BASIS >
1220 real64 const (&X)[4][3] )
1223 GL_BASIS::TensorProduct2D::multiIndex( q, qa, qb );
1224 const real64 w2D = GL_BASIS::weight( qa )*GL_BASIS::weight( qb );
1227 jacobianTransformation2d( qa, qb, X, J );
1229 B[0] = J[0][0]*J[0][0]+J[1][0]*J[1][0]+J[2][0]*J[2][0];
1230 B[1] = J[0][1]*J[0][1]+J[1][1]*J[1][1]+J[2][1]*J[2][1];
1231 B[2] = J[0][0]*J[0][1]+J[1][0]*J[1][1]+J[2][0]*J[2][1];
1232 return sqrt( LvArray::math::abs( LvArray::tensorOps::symDeterminant< 2 >( B ) ) )*w2D;
1235 template<
typename GL_BASIS >
1247 jacobianTransformation( qa, qb, qc, X, J );
1248 real64 const detJ = LvArray::tensorOps::determinant< 3 >( J );
1251 B[0] = (J[0][0]*J[0][0]+J[1][0]*J[1][0]+J[2][0]*J[2][0])/detJ;
1252 B[1] = (J[0][1]*J[0][1]+J[1][1]*J[1][1]+J[2][1]*J[2][1])/detJ;
1253 B[2] = (J[0][2]*J[0][2]+J[1][2]*J[1][2]+J[2][2]*J[2][2])/detJ;
1254 B[3] = (J[0][1]*J[0][2]+J[1][1]*J[1][2]+J[2][1]*J[2][2])/detJ;
1255 B[4] = (J[0][0]*J[0][2]+J[1][0]*J[1][2]+J[2][0]*J[2][2])/detJ;
1256 B[5] = (J[0][0]*J[0][1]+J[1][0]*J[1][1]+J[2][0]*J[2][1])/detJ;
1259 LvArray::tensorOps::symInvert< 3 >( B );
1262 template<
typename GL_BASIS >
1274 jacobianTransformation( qa, qb, qc, X, J );
1275 real64 const detJ = LvArray::tensorOps::determinant< 3 >( J );
1277 real64 Jinv[3][3] = {{0}};
1278 LvArray::tensorOps::invert< 3 >( Jinv, J );
1281 B[0] = detJ*(Jinv[0][2]*Jinv[0][2]);
1282 B[1] = detJ*(Jinv[1][2]*Jinv[1][2]);
1283 B[2] = detJ*(Jinv[2][2]*Jinv[2][2]);
1284 B[3] = detJ*(Jinv[1][2]*Jinv[2][2]);
1285 B[4] = detJ*(Jinv[0][2]*Jinv[2][2]);
1286 B[5] = detJ*(Jinv[0][2]*Jinv[1][2]);
1289 template<
typename GL_BASIS >
1301 jacobianTransformation( qa, qb, qc, X, J );
1302 real64 const detJ = LvArray::tensorOps::determinant< 3 >( J );
1304 real64 Jinv[3][3] = {{0}};
1305 LvArray::tensorOps::invert< 3 >( Jinv, J );
1308 B[0] = detJ*(Jinv[0][0]*Jinv[0][0] + Jinv[0][1]*Jinv[0][1]);
1309 B[1] = detJ*(Jinv[1][1]*Jinv[1][1] + Jinv[1][0]*Jinv[1][0]);
1310 B[2] = detJ*(Jinv[2][0]*Jinv[2][0] + Jinv[2][1]*Jinv[2][1]);
1311 B[3] = detJ*(Jinv[1][0]*Jinv[2][0] + Jinv[1][1]*Jinv[2][1]);
1312 B[4] = detJ*(Jinv[0][0]*Jinv[2][0] + Jinv[0][1]*Jinv[2][1]);
1313 B[5] = detJ*(Jinv[0][0]*Jinv[1][0] + Jinv[0][1]*Jinv[1][1]);
1316 template<
typename GL_BASIS >
1317 template<
typename FUNC >
1328 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1329 for(
int i=0; i<num1dNodes; i++ )
1331 const int ibc = GL_BASIS::TensorProduct3D::linearIndex( i, qb, qc );
1332 const int aic = GL_BASIS::TensorProduct3D::linearIndex( qa, i, qc );
1333 const int abi = GL_BASIS::TensorProduct3D::linearIndex( qa, qb, i );
1334 const real64 gia = basisGradientAt( i, qa );
1335 const real64 gib = basisGradientAt( i, qb );
1336 const real64 gic = basisGradientAt( i, qc );
1337 for(
int j=0; j<num1dNodes; j++ )
1339 const int jbc = GL_BASIS::TensorProduct3D::linearIndex( j, qb, qc );
1340 const int ajc = GL_BASIS::TensorProduct3D::linearIndex( qa, j, qc );
1341 const int abj = GL_BASIS::TensorProduct3D::linearIndex( qa, qb, j );
1342 const real64 gja = basisGradientAt( j, qa );
1343 const real64 gjb = basisGradientAt( j, qb );
1344 const real64 gjc = basisGradientAt( j, qc );
1346 const real64 w0 = w * gia * gja;
1347 func( ibc, jbc, w0 * B[0] );
1348 const real64 w1 = w * gib * gjb;
1349 func( aic, ajc, w1 * B[1] );
1350 const real64 w2 = w * gic * gjc;
1351 func( abi, abj, w2 * B[2] );
1353 const real64 w3 = w * gib * gjc;
1354 func( aic, abj, w3 * B[3] );
1355 func( abj, aic, w3 * B[3] );
1356 const real64 w4 = w * gia * gjc;
1357 func( ibc, abj, w4 * B[4] );
1358 func( abj, ibc, w4 * B[4] );
1359 const real64 w5 = w * gia * gjb;
1360 func( ibc, ajc, w5 * B[5] );
1361 func( ajc, ibc, w5 * B[5] );
1366 template<
typename GL_BASIS >
1367 template<
typename FUNC >
1377 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1380 computeBxyMatrix( qa, qb, qc, X, J, B );
1381 computeGradPhiBGradPhi( qa, qb, qc, B, func );
1384 template<
typename GL_BASIS >
1385 template<
typename FUNC >
1395 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1398 computeBzMatrix( qa, qb, qc, X, J, B );
1399 computeGradPhiBGradPhi( qa, qb, qc, B, func );
1402 template<
typename GL_BASIS >
1403 template<
typename FUNC >
1413 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1416 computeBMatrix( qa, qb, qc, X, J, B );
1417 computeGradPhiBGradPhi( qa, qb, qc, B, func );
1420 template<
typename GL_BASIS >
1421 template<
typename FUNC >
1431 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1433 jacobianTransformation( qa, qb, qc, X, J );
1434 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
1435 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1436 for(
int i=0; i<num1dNodes; i++ )
1438 const int ibc = GL_BASIS::TensorProduct3D::linearIndex( i, qb, qc );
1439 const int aic = GL_BASIS::TensorProduct3D::linearIndex( qa, i, qc );
1440 const int abi = GL_BASIS::TensorProduct3D::linearIndex( qa, qb, i );
1441 const real64 gia = basisGradientAt( i, qa );
1442 const real64 gib = basisGradientAt( i, qb );
1443 const real64 gic = basisGradientAt( i, qc );
1444 for(
int j=0; j<num1dNodes; j++ )
1446 const int jbc = GL_BASIS::TensorProduct3D::linearIndex( j, qb, qc );
1447 const int ajc = GL_BASIS::TensorProduct3D::linearIndex( qa, j, qc );
1448 const int abj = GL_BASIS::TensorProduct3D::linearIndex( qa, qb, j );
1449 const real64 gja = basisGradientAt( j, qa );
1450 const real64 gjb = basisGradientAt( j, qb );
1451 const real64 gjc = basisGradientAt( j, qc );
1453 const real64 w00 = w * gia * gja;
1454 func( ibc, jbc, w00 * detJ, J, 0, 0 );
1455 const real64 w11 = w * gib * gjb;
1456 func( aic, ajc, w11 * detJ, J, 1, 1 );
1457 const real64 w22 = w * gic * gjc;
1458 func( abi, abj, w22 * detJ, J, 2, 2 );
1460 const real64 w12 = w * gib * gjc;
1461 func( aic, abj, w12 * detJ, J, 1, 2 );
1462 func( abj, aic, w12 * detJ, J, 2, 1 );
1463 const real64 w02 = w * gia * gjc;
1464 func( ibc, abj, w02 * detJ, J, 0, 2 );
1465 func( abj, ibc, w02 * detJ, J, 2, 0 );
1466 const real64 w01 = w * gia * gjb;
1467 func( ibc, ajc, w01 * detJ, J, 0, 1 );
1468 func( ajc, ibc, w01 * detJ, J, 1, 0 );
1473 template<
typename GL_BASIS >
1474 template<
typename FUNC >
1484 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1486 jacobianTransformation( qa, qb, qc, X, J );
1487 const real64 detJ = LvArray::tensorOps::invert< 3 >( J );
1488 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1490 for(
int i1 = 0; i1 < num1dNodes; ++i1 )
1492 auto val = w * basisGradientAt( i1, qa );
1493 func( GL_BASIS::TensorProduct3D::linearIndex( i1, qb, qc ), q, detJ*J[0][0]*val, detJ*J[0][1]*val, detJ*J[0][2]*val );
1498 template<
typename GL_BASIS >
1499 template<
typename FUNC >
1509 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1511 jacobianTransformation( qa, qb, qc, X, J );
1512 const real64 detJ = LvArray::tensorOps::invert< 3 >( J );
1513 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1515 for(
int i2 = 0; i2 < num1dNodes; ++i2 )
1517 auto val = w * basisGradientAt( i2, qb );
1518 func( GL_BASIS::TensorProduct3D::linearIndex( qa, i2, qc ), q, detJ*J[1][0]*val, detJ*J[1][1]*val, detJ*J[1][2]*val );
1522 template<
typename GL_BASIS >
1523 template<
typename FUNC >
1533 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1535 jacobianTransformation( qa, qb, qc, X, J );
1536 const real64 detJ = LvArray::tensorOps::invert< 3 >( J );
1537 const real64 w = GL_BASIS::weight( qa )*GL_BASIS::weight( qb )*GL_BASIS::weight( qc );
1539 for(
int i3 = 0; i3 < num1dNodes; ++i3 )
1541 auto val = w * basisGradientAt( i3, qc );
1542 func( GL_BASIS::TensorProduct3D::linearIndex( qa, qb, i3 ), q, detJ*J[2][0]*val, detJ*J[2][1]*val, detJ*J[2][2]*val );
1547 template<
typename GL_BASIS >
1553 real64 const ( &invJ )[3][3],
1554 real64 (& gradN)[numNodes][3] )
1557 int const nodeIndex,
1558 real64 const (&invJ)[3][3],
1559 real64 (& gradN)[numNodes][3] )
1562 gradN[nodeIndex][0] = dNdXi[0] * invJ[0][0] + dNdXi[1] * invJ[1][0] + dNdXi[2] * invJ[2][0];
1563 gradN[nodeIndex][1] = dNdXi[0] * invJ[0][1] + dNdXi[1] * invJ[1][1] + dNdXi[2] * invJ[2][1];
1564 gradN[nodeIndex][2] = dNdXi[0] * invJ[0][2] + dNdXi[1] * invJ[1][2] + dNdXi[2] * invJ[2][2];
1571 template<
typename GL_BASIS >
1577 real64 const ( &invJ )[3][3],
1578 real64 (& gradN)[numNodes][3] )
1581 int const nodeIndex,
1582 real64 const (&invJ)[3][3],
1583 real64 (& gradN)[numNodes][3] )
1585 gradN[nodeIndex][0] = dNdXi[0] * invJ[0][0] + dNdXi[1] * invJ[1][0] + dNdXi[2] * invJ[2][0];
1586 gradN[nodeIndex][1] = dNdXi[0] * invJ[0][1] + dNdXi[1] * invJ[1][1] + dNdXi[2] * invJ[2][1];
1587 gradN[nodeIndex][2] = dNdXi[0] * invJ[0][2] + dNdXi[1] * invJ[1][2] + dNdXi[2] * invJ[2][2];
1591 template<
typename GL_BASIS >
1597 real64 const (&X)[numNodes][3] )
1600 GL_BASIS::TensorProduct3D::multiIndex( q, qa, qb, qc );
1603 jacobianTransformation( qa, qb, qc, X, J );
1605 return LvArray::tensorOps::determinant< 3 >( J );
1610 template<
typename GL_BASIS >
1615 real64 const (&invJ)[3][3],
1616 real64 const (&var)[numNodes][3],
1620 int const nodeIndex,
1621 real64 const (&invJ)[3][3],
1622 real64 const (&var)[numNodes][3],
1626 real64 gradN[3] = {0, 0, 0};
1627 for(
int i = 0; i < 3; ++i )
1629 for(
int j = 0; j < 3; ++j )
1631 gradN[i] = gradN[i] + dNdXi[ j ] * invJ[j][i];
1635 grad[0] = grad[0] + gradN[0] * var[ nodeIndex ][0];
1636 grad[1] = grad[1] + gradN[1] * var[ nodeIndex ][1];
1637 grad[2] = grad[2] + gradN[2] * var[ nodeIndex ][2];
1638 grad[3] = grad[3] + gradN[2] * var[ nodeIndex ][1] + gradN[1] * var[ nodeIndex ][2];
1639 grad[4] = grad[4] + gradN[2] * var[ nodeIndex ][0] + gradN[0] * var[ nodeIndex ][2];
1640 grad[5] = grad[5] + gradN[1] * var[ nodeIndex ][0] + gradN[0] * var[ nodeIndex ][1];
1641 }, invJ, var, grad );
1644 template<
typename GL_BASIS >
1649 real64 const (&invJ)[3][3],
1651 real64 (& R)[numNodes][3] )
1655 (
real64 const (&dNdXi)[3],
1656 int const nodeIndex,
1657 real64 const (&invJ)[3][3],
1659 real64 (& R)[numNodes][3] )
1662 real64 gradN[3] = {0, 0, 0};
1663 for(
int i = 0; i < 3; ++i )
1665 for(
int j = 0; j < 3; ++j )
1667 gradN[i] = gradN[i] + dNdXi[ j ] * invJ[j][i];
1670 R[ nodeIndex ][ 0 ] = R[ nodeIndex ][ 0 ] - var[ 0 ] * gradN[ 0 ] - var[ 5 ] * gradN[ 1 ] - var[ 4 ] * gradN[ 2 ];
1671 R[ nodeIndex ][ 1 ] = R[ nodeIndex ][ 1 ] - var[ 5 ] * gradN[ 0 ] - var[ 1 ] * gradN[ 1 ] - var[ 3 ] * gradN[ 2 ];
1672 R[ nodeIndex ][ 2 ] = R[ nodeIndex ][ 2 ] - var[ 4 ] * gradN[ 0 ] - var[ 3 ] * gradN[ 1 ] - var[ 2 ] * gradN[ 2 ];
1678 template<
typename GL_BASIS >
1683 real64 const (&invJ)[3][3],
1684 real64 const (&var)[numNodes][3],
1688 int const nodeIndex,
1689 real64 const (&invJ)[3][3],
1690 real64 const (&var)[numNodes][3],
1693 for(
int i = 0; i < 3; ++i )
1696 for(
int j = 0; j < 3; ++j )
1698 gradN = gradN + dNdXi[ j ] * invJ[j][i];
1700 for(
int k = 0; k < 3; ++k )
1702 grad[k][i] = grad[k][i] + gradN * var[ nodeIndex ][k];
1705 }, invJ, var, grad );
1733 using Q1_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis1 >;
1776 using Q2_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis2 >;
1820 using Q3_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis3GL >;
1858 using Q4_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis4GL >;
1910 using Q5_Hexahedron_Lagrange_GaussLobatto = Qk_Hexahedron_Lagrange_GaussLobatto< LagrangeBasis5GL >;
1915 #pragma GCC diagnostic pop
1917 #undef PARENT_GRADIENT_METHOD
#define USING_FINITEELEMENTBASE
Macro to simplify name resolution in derived classes.
#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.
Base class for FEM element implementations.
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...
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 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 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 computeLocalCoords(real64 const (&Xmesh)[8][3], real64 const (&X)[numNodes][3])
computes the real-world coordinates of the support nodes
constexpr static localIndex maxSupportPoints
The maximum number of support points per element.
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 void calcN(real64 const (&coords)[3], real64(&N)[numNodes])
Calculate shape functions values at a single point.
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.
~Qk_Hexahedron_Lagrange_GaussLobatto()=default
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 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,...
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 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 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 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.
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 virtual GEOS_FORCE_INLINE localIndex getMaxSupportPoints() const override
Get the maximum number of support points for this element.
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 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 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 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.
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.
constexpr static localIndex num1dNodes
The number of nodes/support points per element per dimension.
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,...
virtual GEOS_HOST_DEVICE localIndex getNumQuadraturePoints() const override
Virtual getter for the number of quadrature points per element.
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 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...
constexpr static localIndex numQuadraturePoints
The number of quadrature points per element.
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 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 virtual GEOS_FORCE_INLINE localIndex getNumSupportPoints() const override
Virtual getter for the number of support points per element.
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 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 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 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),...
constexpr static localIndex numNodesPerFace
The number of nodes/support points per face.
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 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 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 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 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...
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE localIndex getNumSupportPoints(StackVariables const &stack)
Get the number of support points.
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 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,...
constexpr static localIndex numNodes
The number of nodes/support points per element.
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 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 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 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 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 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 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 real64 calcGradN(localIndex const q, real64 const (&X)[numNodes][3], real64(&gradN)[numNodes][3])
Calculate the shape functions derivatives wrt the physical coordinates.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Kernel variables allocated on the stack.