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 (dof numbers, jacobian and residual) located on the stack.
 
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.