20 #ifndef GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_PKPYRAMIDBCD_HPP_
21 #define GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_PKPYRAMIDBCD_HPP_
24 #include "denseLinearAlgebra/interfaces/blaslapack/BlasLapackLA.hpp"
47 static constexpr
int order = ORDER;
145 for(
int l = 0; l < qc; ++l )
147 int n =
order + 1 - l;
150 int n_k =
order + 1 - qc;
151 index += qa + qb * n_k;
166 if constexpr (ORDER == 1)
168 coords[0][0] = -1.0; coords[0][1] = 1.0; coords[0][2] = 0.0;
169 coords[1][0] = -1.0; coords[1][1] = -1.0; coords[1][2] = 0.0;
170 coords[2][0] = 1.0; coords[2][1] = -1.0; coords[2][2] = 0.0;
171 coords[3][0] = 1.0; coords[3][1] = 1.0; coords[3][2] = 0.0;
172 coords[4][0] = 0.0; coords[4][1] = 0.0; coords[4][2] = 1.0;
174 else if constexpr (ORDER == 2)
186 template<
typename FUNC >
196 localIndex maxIj = LvArray::math::max( i, j );
197 for(
localIndex k = 0; k <= ORDER - maxIj; ++k )
218 for(
int i = 0; i < 4; i++ )
220 for(
int j = 0; j < 3; j++ )
222 m[ i ][ j ] = X[ i + 1 ][ j ] - X[ 0 ][ j ];
225 return LvArray::math::abs( LvArray::tensorOps::determinant< 3 >( m ) );
240 int i1 = ( face + 1 ) % 4;
241 int i2 = ( face + 2 ) % 4;
242 int i3 = ( face + 3 ) % 4;
244 real64 ab[3] = { X[ i2 ][ 0 ] - X[ i1 ][ 0 ],
245 X[ i2 ][ 1 ] - X[ i1 ][ 1 ],
246 X[ i2 ][ 2 ] - X[ i1 ][ 2 ] };
247 real64 ac[3] = { X[ i3 ][ 0 ] - X[ i1 ][ 0 ],
248 X[ i3 ][ 1 ] - X[ i1 ][ 1 ],
249 X[ i3 ][ 2 ] - X[ i1 ][ 2 ] };
250 real64 term1 = ab[1] * ac[2] - ab[2] * ac[1];
251 real64 term2 = ab[2] * ac[0] - ab[0] * ac[2];
252 real64 term3 = ab[0] * ac[1] - ab[1] * ac[0];
253 return LvArray::math::sqrt( ( term1 * term1 + term2 * term2 + term3 * term3 ) );
272 return calcN( q, N );
297 real64 val = 0.5 * (alpha - beta + (alpha + beta + 2) * x);
303 real64 P_prev1 = 0.5 * (alpha - beta + (alpha + beta + 2) * x);
307 for(
int k = 2; k < n+1; ++k )
309 real64 a_k = 2 * k * (k + alpha + beta) * (2 * k + alpha + beta - 2);
310 real64 b_k = (2 * k + alpha + beta - 1) * (alpha * alpha - beta * beta);
311 real64 c_k = (2 * k + alpha + beta - 1) * (2 * k + alpha + beta) * (2 * k + alpha + beta - 2);
312 real64 d_k = 2 * (k + alpha - 1) * (k + beta - 1) * (2 * k + alpha + beta);
314 P_current = ((b_k + c_k * x) * P_prev1 - d_k * P_prev2) / a_k;
343 real64 coeff = 0.5 * (n + alpha + beta + 1.0);
346 return coeff * jacobi_nm1;
365 real64 const epsilon = 1e-10;
366 if( LvArray::math::abs( z-1.0 ) < epsilon )
368 if( i == 0 && j == 0 )
370 return (k+2)*(k+1)/2.0;
378 real64 xi = x / (1.0 - z);
379 real64 eta = y / (1.0 - z);
380 real64 chi = 2.0 * z - 1.0;
381 localIndex max_ij = LvArray::math::max( i, j );
386 return P_i * P_j * std::pow( 1.0 - z, max_ij ) * P_k;
406 real64 const epsilon = 1e-10;
407 if( LvArray::math::abs( z-1.0 ) < epsilon )
416 real64 xi = x / (1.0 - z);
417 real64 eta = y / (1.0 - z);
418 real64 chi = 2.0 * z - 1.0;
427 real64 f = pow( 1.0 - z, m );
429 gradPsiX[0] = (1.0 / (1.0 - z)) * dP_i * P_j * f * P_k;
432 gradPsiX[1] = (1.0 / (1.0 - z)) * dP_j * P_i * f * P_k;
435 real64 dxi_dz = x / std::pow( 1.0 - z, 2 );
436 real64 deta_dz = y / std::pow( 1.0 - z, 2 );
438 real64 df_dz = -m * std::pow( 1.0 - z, m - 1 );
440 dP_i * dxi_dz * P_j * f * P_k +
441 P_i * dP_j * deta_dz * f * P_k +
442 P_i * P_j * df_dz * P_k +
443 P_i * P_j * f * dP_k * dchi_dz;
467 PsiX[count]=
calcModal( p, r, s, coords[j] );
468 VDM[count][j] = PsiX[count];
476 BlasLapackLA::matrixInverse( VDM, VDM_inv );
502 PsiX[count] =
calcModal( p, r, s, coords[q] );
512 N[i] += VDM_inv[i][j] * PsiX[j];
544 N[i] += VDM_inv[i][j] * PsiX[j];
584 gradN[i][0] += VDM_inv[i][j] * gradModal[j][0];
585 gradN[i][1] += VDM_inv[i][j] * gradModal[j][1];
586 gradN[i][2] += VDM_inv[i][j] * gradModal[j][2];
621 gradN[i][0] += VDM_inv[i][j] * gradModal[j][0];
622 gradN[i][1] += VDM_inv[i][j] * gradModal[j][1];
623 gradN[i][2] += VDM_inv[i][j] * gradModal[j][2];
636 template<
typename FUNC >
643 constexpr
real64 GLeQuadraturePoints[3] = { -0.7745966692, 0.0, 0.7745966692 };
644 constexpr
real64 GLeQuadratureWeights[3] = { 0.5555555556, 0.8888888889, 0.5555555556 };
646 constexpr
real64 GJQuadraturePoints[3] = { 0.07299, 0.34700, 0.70500 };
647 constexpr
real64 GJQuadratureWeights[3] = { 0.15714, 0.14625, 0.02995 };
657 for(
int i = 0; i < 3; ++i )
659 for(
int j = 0; j < 3; ++j )
661 for(
int k = 0; k < 3; ++k )
664 real64 xi = GLeQuadraturePoints[i];
665 real64 eta = GLeQuadraturePoints[j];
666 real64 chi = GJQuadraturePoints[k];
668 real64 weight = GLeQuadratureWeights[i] * GLeQuadratureWeights[j] * GJQuadratureWeights[k];
672 real64 X[3] = {x_i, y_j, z_k};
674 calcN( X, VDM_inv, N );
676 val += weight * N[a] * N[b];
693 template<
typename FUNC >
699 constexpr
real64 GLeQuadraturePoints[3] = { -0.7745966692, 0.0, 0.7745966692 };
700 constexpr
real64 GLeQuadratureWeights[3] = { 0.5555555556, 0.8888888889, 0.5555555556 };
702 constexpr
real64 GJQuadraturePoints[3] = { 0.07299, 0.34700, 0.70500 };
703 constexpr
real64 GJQuadratureWeights[3] = { 0.15714, 0.14625, 0.02995 };
714 for(
int i = 0; i < 3; ++i )
716 for(
int j = 0; j < 3; ++j )
718 for(
int k = 0; k < 3; ++k )
720 real64 xi = GLeQuadraturePoints[i];
721 real64 eta = GLeQuadraturePoints[j];
722 real64 chi = GJQuadraturePoints[k];
724 real64 weight = GLeQuadratureWeights[i] * GLeQuadratureWeights[j] * GJQuadratureWeights[k];
728 real64 X[3] = {x_i, y_j, z_k};
731 real64 dot = gradN[a][0] * gradN[b][0]
732 + gradN[a][1] * gradN[b][1]
733 + gradN[a][2] * gradN[b][2];
#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.
Base class for FEM element implementations.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE void generatePointsCoordinates(real64(&coords)[numNodes][3])
Generate the coordinates of the support points.
constexpr static localIndex numModes
The number of modal points per element.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE void calcN(localIndex q, arrayView2d< real64 const > VDM_inv, real64(&N)[numNodes])
Evaluate shape functions of a linear pyramid (5-node) at a quadrature point.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE localIndex getNumSupportPoints(StackVariables const &stack)
Get the number of support points.
GEOS_HOST_DEVICE virtual GEOS_FORCE_INLINE localIndex getMaxSupportPoints() const override
Get the maximum number of support points for this element.
constexpr static localIndex numQuadraturePoints
The number of quadrature points per element.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE real64 calcModal(localIndex const i, localIndex const j, localIndex const k, real64 const (&X)[3])
Calculate modal base functions values for a modal point (i,j,k) at a point X.
static constexpr int order
The order of the finite element.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE localIndex getNumModes(StackVariables const &stack)
Get the number of modal points.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE void calcGradModal(int i, int j, int k, real64 const (&X)[3], real64(&gradPsiX)[3])
Calculate modal base functions derivative values for a modal point (i,j,k) at a point X.
constexpr static localIndex numNodes
The number of shape functions per element.
virtual ~Pk_Pyramid_BCD()=default
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 jacobianDeterminant(real64 const (&X)[5][3])
Returns the determinant of the Jacobian of the element.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE real64 EvaluateJacobiPolynomial(localIndex const n, real64 const alpha, real64 const beta, real64 const x)
Helper to compute Jacobi Polynomials.
static GEOS_FORCE_INLINE array2d< real64 > computeVanderMondeMatrixInverse()
Compute the inverse of the VanDerMonde matrix.
virtual GEOS_HOST_DEVICE localIndex getNumQuadraturePoints() const override
Virtual getter for the number of quadrature points per element.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE void calcN(real64 const (&X)[3], arrayView2d< real64 const > VDM_inv, real64(&N)[numNodes])
Evaluate shape functions of a linear pyramid (5-node) at a quadrature point.
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/nodal point.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE void generateIndexes(FUNC &&func)
Generate the indexes for the modal shape functions.
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 constexpr GEOS_FORCE_INLINE void calcGradN(localIndex q, arrayView2d< real64 const > VDM_inv, real64(&gradN)[numNodes][3])
Evaluate shape functions of a linear pyramid (5-node) at a quadrature point.
constexpr static localIndex numFaces
The number of faces points per element.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE real64 faceJacobianDeterminant(localIndex face, real64 const (&X)[5][3])
Calculate the determinant of the jacobian on the face opposite to the given vertex.
GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void computeStiffnessTerm(arrayView2d< real64 const > VDM_inv, FUNC &&func)
Computes the stifness term Kij in the mass matrix.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE void computeMassTerm(arrayView2d< real64 const > VDM_inv, FUNC &&func)
Computes the mass term Mij in the mass matrix.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE void calcGradN(real64 const (&X)[3], arrayView2d< real64 const > VDM_inv, real64(&gradN)[numNodes][3])
Evaluate shape functions of a linear pyramid (5-node) at a given point.
GEOS_HOST_DEVICE static constexpr GEOS_FORCE_INLINE real64 EvaluateJacobiPolynomialDerivative(localIndex const n, real64 const alpha, real64 const beta, real64 const x)
Evaluate the derivative of the Jacobi polynomial at a point x.
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.
constexpr static localIndex maxSupportPoints
The maximum number of support points per element.
Array< T, 2, PERMUTATION > array2d
Alias for 2D array.
double real64
64-bit floating point type.
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
ArrayView< T, 2, USD > arrayView2d
Alias for 2D array view.
Kernel variables allocated on the stack.