20 #ifndef GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_TRILINEARHEXAHEDRON_HPP_
21 #define GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_TRILINEARHEXAHEDRON_HPP_
151 real64 (& samplingPointCoord)[3] )
159 samplingPointCoord[0] = -1 + i0 * step;
160 samplingPointCoord[1] = -1 + i1 * step;
161 samplingPointCoord[2] = -1 + i2 * step;
215 return calcN( q, N );
342 return LvArray::tensorOps::invert< 3 >( J );
358 real64 const (&invJ)[3][3],
381 real64 const (&invJ)[3][3],
403 real64 const (&invJ)[3][3],
442 real64 const ( &invJ )[3][3],
451 constexpr
static real64 parentVolume = parentLength*parentLength*parentLength;
459 constexpr
static real64 quadratureFactor = 1.0 / 1.732050807568877293528;
480 template<
typename FUNC,
typename ... PARAMS >
482 static void supportLoop(
int const qa,
486 PARAMS &&... params );
505 template<
typename FUNC,
typename ... PARAMS >
507 H1_Hexahedron_Lagrange1_GaussLegendre2::supportLoop(
int const qa,
511 PARAMS &&... params )
515 #define PARENT_GRADIENT_METHOD 2
516 #if PARENT_GRADIENT_METHOD == 1
520 real64 const quadratureCoords[3] = { -quadratureFactor + 1.154700538379252 * qa,
521 -quadratureFactor + 1.154700538379252 * qb,
522 -quadratureFactor + 1.154700538379252 * qc };
524 real64 const psi0[2] = { 0.5 - 0.5 * quadratureCoords[0],
525 0.5 + 0.5 * quadratureCoords[0] };
526 real64 const psi1[2] = { 0.5 - 0.5 * quadratureCoords[1],
527 0.5 + 0.5 * quadratureCoords[1] };
528 real64 const psi2[2] = { 0.5 - 0.5 * quadratureCoords[2],
529 0.5 + 0.5 * quadratureCoords[2] };
530 constexpr
real64 dpsi[2] = { -0.5, 0.5 };
531 #elif PARENT_GRADIENT_METHOD == 2
551 constexpr
static real64 psiProduct[3] = { 0.311004233964073108, 0.083333333333333333, 0.022329099369260226};
552 constexpr
static int dpsi[2] = { -1, 1 };
559 for(
int a=0; a<2; ++a )
561 #if PARENT_GRADIENT_METHOD == 2
562 int const qaa = ( a^qa );
564 for(
int b=0; b<2; ++b )
566 #if PARENT_GRADIENT_METHOD == 2
567 int const qbb = ( b^qb );
569 for(
int c=0; c<2; ++c )
571 #if PARENT_GRADIENT_METHOD == 2
572 int const qcc = ( c^qc );
575 #if PARENT_GRADIENT_METHOD == 1
576 real64 const dNdXi[3] = { dpsi[a] * psi1[b] * psi2[c],
577 psi0[a] * dpsi[b] * psi2[c],
578 psi0[a] * psi1[b] * dpsi[c] };
579 #elif PARENT_GRADIENT_METHOD == 2
586 real64 const dNdXi[3] = { dpsi[a] * psiProduct[ qbb + qcc ],
587 dpsi[b] * psiProduct[ qaa + qcc ],
588 dpsi[c] * psiProduct[ qaa + qbb ] };
592 func( dNdXi, nodeIndex, std::forward< PARAMS >( params )... );
603 real64 const (&X)[numNodes][3],
604 real64 (& gradN)[numNodes][3] )
614 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
618 return detJ * weight;
625 real64 const (&X)[numNodes][3],
627 real64 ( & gradN )[numNodes][3] )
636 real64 const (&X)[numNodes][3],
637 real64 (& gradN)[numFaces][3] )
647 real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
659 gradN[fi][0] = dNdXi[fi][0] * J[0][0] + dNdXi[fi][1] * J[1][0] + dNdXi[fi][2] * J[2][0];
660 gradN[fi][1] = dNdXi[fi][0] * J[0][1] + dNdXi[fi][1] * J[1][1] + dNdXi[fi][2] * J[2][1];
661 gradN[fi][2] = dNdXi[fi][0] * J[0][2] + dNdXi[fi][1] * J[1][2] + dNdXi[fi][2] * J[2][2];
664 return detJ * weight;
669 #pragma GCC diagnostic push
670 #pragma GCC diagnostic ignored "-Wshadow"
680 real64 const (&X)[numNodes][3],
689 for(
int i = 0; i < 3; ++i )
691 for(
int j = 0; j < 3; ++j )
693 J[i][j] = J[i][j] + dNdXi[ j ] * Xnode[i];
719 real64 const ( &invJ )[3][3],
720 real64 (& gradN)[numNodes][3] )
724 real64 const (&invJ)[3][3],
736 gradN[nodeIndex][0] = dNdXi[0] * invJ[0][0] + dNdXi[1] * invJ[1][0] + dNdXi[2] * invJ[2][0];
737 gradN[nodeIndex][1] = dNdXi[0] * invJ[0][1] + dNdXi[1] * invJ[1][1] + dNdXi[2] * invJ[2][1];
738 gradN[nodeIndex][2] = dNdXi[0] * invJ[0][2] + dNdXi[1] * invJ[1][2] + dNdXi[2] * invJ[2][2];
750 real64 const (&X)[numNodes][3] )
759 return LvArray::tensorOps::determinant< 3 >( J );
767 real64 const (&invJ)[3][3],
768 real64 const (&var)[numNodes][3],
776 real64 const (&invJ)[3][3],
781 real64 gradN[3] = {0, 0, 0};
782 for(
int i = 0; i < 3; ++i )
784 for(
int j = 0; j < 3; ++j )
786 gradN[i] = gradN[i] + dNdXi[ j ] * invJ[j][i];
790 grad[0] = grad[0] + gradN[0] * var[ nodeIndex ][0];
791 grad[1] = grad[1] + gradN[1] * var[ nodeIndex ][1];
792 grad[2] = grad[2] + gradN[2] * var[ nodeIndex ][2];
793 grad[3] = grad[3] + gradN[2] * var[ nodeIndex ][1] + gradN[1] * var[ nodeIndex ][2];
794 grad[4] = grad[4] + gradN[2] * var[ nodeIndex ][0] + gradN[0] * var[ nodeIndex ][2];
795 grad[5] = grad[5] + gradN[1] * var[ nodeIndex ][0] + gradN[0] * var[ nodeIndex ][1];
796 }, invJ, var, grad );
802 real64 const (&invJ)[3][3],
804 real64 (& R)[numNodes][3] )
809 supportLoop( qa, qb, qc,
811 (
real64 const (&dNdXi)[3],
813 real64 const (&invJ)[3][3],
818 real64 gradN[3] = {0, 0, 0};
819 for(
int i = 0; i < 3; ++i )
821 for(
int j = 0; j < 3; ++j )
823 gradN[i] = gradN[i] + dNdXi[ j ] * invJ[j][i];
826 R[ nodeIndex ][ 0 ] = R[ nodeIndex ][ 0 ] - var[ 0 ] * gradN[ 0 ] - var[ 5 ] * gradN[ 1 ] - var[ 4 ] * gradN[ 2 ];
827 R[ nodeIndex ][ 1 ] = R[ nodeIndex ][ 1 ] - var[ 5 ] * gradN[ 0 ] - var[ 1 ] * gradN[ 1 ] - var[ 3 ] * gradN[ 2 ];
828 R[ nodeIndex ][ 2 ] = R[ nodeIndex ][ 2 ] - var[ 4 ] * gradN[ 0 ] - var[ 3 ] * gradN[ 1 ] - var[ 2 ] * gradN[ 2 ];
837 real64 const (&invJ)[3][3],
838 real64 const (&var)[numNodes][3],
846 real64 const (&invJ)[3][3],
850 for(
int i = 0; i < 3; ++i )
853 for(
int j = 0; j < 3; ++j )
855 gradN = gradN + dNdXi[ j ] * invJ[j][i];
857 for(
int k = 0; k < 3; ++k )
859 grad[k][i] = grad[k][i] + gradN * var[ nodeIndex ][k];
862 }, invJ, var, grad );
868 #pragma GCC diagnostic pop
871 #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.
constexpr static int numSamplingPointsPerDirection
Number of sampling points.
constexpr static localIndex maxSupportPoints
The maximum number of support points per element.
static GEOS_HOST_DEVICE 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 getSamplingPointCoordInParentSpace(int const linearIndex, real64(&samplingPointCoord)[3])
Get the Sampling Point Coord In the Parent Space.
static GEOS_HOST_DEVICE 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.
virtual GEOS_HOST_DEVICE localIndex getMaxSupportPoints() const override
Get the maximum number of support points for this element.
static GEOS_HOST_DEVICE void calcN(localIndex const q, StackVariables const &stack, real64(&N)[numNodes])
Calculate shape functions values for each support point at a quadrature point.
virtual GEOS_HOST_DEVICE ~H1_Hexahedron_Lagrange1_GaussLegendre2() override
constexpr static localIndex numNodes
The number of nodes/support points per element.
static GEOS_HOST_DEVICE void applyTransformationToParentGradients(int const qa, int const qb, int const qc, 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...
virtual GEOS_HOST_DEVICE localIndex getNumSupportPoints() const override
Virtual getter for the number of support points per element.
static GEOS_HOST_DEVICE localIndex getNumSupportPoints(StackVariables const &stack)
Get the number of support points.
static GEOS_HOST_DEVICE 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...
static GEOS_HOST_DEVICE real64 calcGradN(localIndex const q, real64 const (&X)[numNodes][3], real64(&gradN)[numNodes][3])
Calculate the shape functions derivatives wrt the physical coordinates.
static GEOS_HOST_DEVICE localIndex getNumQuadraturePoints(StackVariables const &stack)
Get the number of quadrature points.
static GEOS_HOST_DEVICE void jacobianTransformation(int const qa, int const qb, int const qc, real64 const (&X)[numNodes][3], real64(&J)[3][3])
Calculates the isoparametric "Jacobian" transformation matrix/mapping from the parent space to the ph...
static GEOS_HOST_DEVICE 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...
constexpr static int numSamplingPoints
The number of sampling points per element.
static GEOS_HOST_DEVICE real64 transformedQuadratureWeight(localIndex const q, real64 const (&X)[numNodes][3], StackVariables const &stack)
Calculate the integration weights for a quadrature point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void calcFaceBubbleN(real64 const (&pointCoord)[3], real64(&N)[numFaces])
Calculate face bubble functions values for each face at a given point in the parent space.
virtual GEOS_HOST_DEVICE localIndex getNumQuadraturePoints() const override
Virtual getter for the number of quadrature points per element.
constexpr static localIndex numQuadraturePoints
The number of quadrature points per element.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void calcN(real64 const (&pointCoord)[3], real64(&N)[numNodes])
Calculate shape functions values for each support point at a given point in the parent space.
static GEOS_HOST_DEVICE real64 transformedQuadratureWeight(localIndex const q, real64 const (&X)[numNodes][3])
Calculate the integration weights for a quadrature point.
constexpr static localIndex numFaces
The number of faces/support points for bubble functions per element.
static GEOS_HOST_DEVICE real64 calcGradFaceBubbleN(localIndex const q, real64 const (&X)[numNodes][3], real64(&gradN)[numFaces][3])
Calculate the bubble function derivatives wrt the physical coordinates.
static GEOS_HOST_DEVICE void calcFaceBubbleN(localIndex const q, real64(&N)[numFaces])
Calculate face bubble functions values for each face at a quadrature point.
static GEOS_HOST_DEVICE real64 invJacobianTransformation(int const q, real64 const (&X)[numNodes][3], real64(&J)[3][3])
Calculates the isoparametric "Jacobian" transformation matrix/mapping from the parent space to the ph...
static GEOS_HOST_DEVICE 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 constexpr static GEOS_FORCE_INLINE real64 parentSupportCoord(const localIndex supportPointIndex)
Calculate the parent coordinates for the xi0 direction, given the linear index of a support point.
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.
constexpr static localIndex numSupportPoints
The number of support points in the basis.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void value(real64 const (&coords)[3], real64(&N)[numSupportPoints])
The value of the basis function for a support point evaluated at a point along the axes.
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE void multiIndex(const int linearIndex, int &i0, int &i1, int &i2)
Calculate the Cartesian/TensorProduct index given the linear index of a support point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void gradientFaceBubble(real64 const (&coords)[3], real64(&dNdXi)[numSupportFaces][3])
The value of the bubble basis function derivatives for a support face evaluated at a point along the ...
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE int linearIndex(const int i, const int j, const int k)
Calculates the linear index for support/quadrature points from ijk coordinates.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void valueFaceBubble(real64 const (&coords)[3], real64(&N)[numSupportFaces])
The value of the bubble basis function for a support face evaluated at a point along the axes.
constexpr static localIndex numSupportFaces
The number of support faces in the basis.