GEOS
H1_Pyramid_Lagrange1_Gauss5.hpp
Go to the documentation of this file.
1 /*
2  * ------------------------------------------------------------------------------------------------------------
3  * SPDX-License-Identifier: LGPL-2.1-only
4  *
5  * Copyright (c) 2016-2024 Lawrence Livermore National Security LLC
6  * Copyright (c) 2018-2024 TotalEnergies
7  * Copyright (c) 2018-2024 The Board of Trustees of the Leland Stanford Junior University
8  * Copyright (c) 2023-2024 Chevron
9  * Copyright (c) 2019- GEOS/GEOSX Contributors
10  * All rights reserved
11  *
12  * See top level LICENSE, COPYRIGHT, CONTRIBUTORS, NOTICE, and ACKNOWLEDGEMENTS files for details.
13  * ------------------------------------------------------------------------------------------------------------
14  */
15 
20 #ifndef GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_H1PYRAMIDLAGRANGE1GAUSS5_HPP_
21 #define GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_H1PYRAMIDLAGRANGE1GAUSS5_HPP_
22 
23 #include "FiniteElementBase.hpp"
24 #include "LagrangeBasis1.hpp"
25 
26 
27 namespace geos
28 {
29 namespace finiteElement
30 {
31 
59 {
60 public:
61 
64 
65 
68  {};
69 
71  template< typename SUBREGION_TYPE >
72  struct MeshData {};
73 
82 
90  static void calcN( real64 const (&pointCoord)[3],
91  real64 ( &N )[numNodes] );
92 
101  static void calcN( localIndex const q,
102  real64 ( &N )[numNodes] );
103 
113  inline
114  static void calcN( localIndex const q,
115  StackVariables const & stack,
116  real64 ( &N )[numNodes] );
117 
127  static void calcFaceBubbleN( real64 const (&pointCoord)[3],
128  real64 (& N)[numFaces] )
129  {
130  GEOS_UNUSED_VAR( pointCoord, N );
131  GEOS_ERROR( "Unsupported bubble functions for pyramid elements" );
132  }
133 
142  inline
143  static void calcFaceBubbleN( localIndex const q,
144  real64 (& N)[numFaces] )
145  {
146  GEOS_UNUSED_VAR( q, N );
147  GEOS_ERROR( "Unsupported bubble functions for pyramid elements" );
148  }
149 
159  static
161  real64 const (&X)[numNodes][3],
162  real64 ( &J )[3][3] );
163 
174  static
176  real64 const (&X)[numNodes][3],
177  StackVariables const &stack,
178  real64 ( &J )[3][3] );
179 
190  static real64 calcGradN( localIndex const q,
191  real64 const (&X)[numNodes][3],
192  real64 ( &gradN )[numNodes][3] );
193 
205  inline
206  static real64 calcGradN( localIndex const q,
207  real64 const (&X)[numNodes][3],
208  StackVariables const & stack,
209  real64 ( &gradN )[numNodes][3] );
210 
222  real64 const (&X)[numNodes][3],
223  real64 ( &gradN )[numFaces][3] );
224 
234  real64 const (&X)[numNodes][3] );
235 
246  real64 const (&X)[numNodes][3],
247  StackVariables const & stack )
248  { GEOS_UNUSED_VAR( stack ); return transformedQuadratureWeight( q, X ); }
249 
259  static real64 invJacobianTransformation( int const q,
260  real64 const (&X)[numNodes][3],
261  real64 ( & J )[3][3] )
262  {
263  jacobianTransformation( q, X, J );
264  return LvArray::tensorOps::invert< 3 >( J );
265  }
266 
267 private:
269  constexpr static real64 weight = 81.0 / 100.0;
270 
272  constexpr static real64 weightDelta = 125.0 / 27.0 - weight;
273 
277  constexpr static real64 quadratureCrossSectionCoord = 0.584237394672177;
278 
281  constexpr static real64 quadratureLongitudinalCoordNeg = -2.0 / 3.0;
282 
285  constexpr static real64 quadratureLongitudinalCoordDelta = 16.0 / 15.0;
286 
294  template< typename T >
296  inline
297  constexpr static T linearMap( T const i, T const j )
298  {
299  return i + 2 * j;
300  }
301 
309  inline
310  constexpr static real64 parentCoords0( localIndex const a )
311  {
312  return -1.0 + 2.0 * ( a & 1 ) + 0.25 * ( a & 4 );
313  }
314 
322  inline
323  constexpr static real64 parentCoords1( localIndex const a )
324  {
325  return -1.0 + ( a & 2 ) + 0.25 * ( a & 4 );
326  }
327 
335  inline
336  constexpr static real64 parentCoords2( localIndex const a )
337  {
338  return -1.0 + 0.5 * ( a & 4 );
339  }
340 
348  inline
349  constexpr static real64 quadratureParentCoords0( localIndex const q )
350  {
351  return parentCoords0( q ) * quadratureCrossSectionCoord;
352  }
353 
361  inline
362  constexpr static real64 quadratureParentCoords1( localIndex const q )
363  {
364  return parentCoords1( q ) * quadratureCrossSectionCoord;
365  }
366 
374  inline
375  constexpr static real64 quadratureParentCoords2( localIndex const q )
376  {
377  return quadratureLongitudinalCoordNeg + 0.5 * ( 1 + parentCoords2( q ) ) * quadratureLongitudinalCoordDelta;
378  }
379 
386  inline
387  constexpr static real64 quadratureWeight( localIndex const q )
388  {
389  return weight + 0.5 * ( 1 + parentCoords2( q ) ) * weightDelta;
390  }
391 
399  static void jacobianTransformation( int const q,
400  real64 const (&X)[numNodes][3],
401  real64 ( &J )[3][3] );
402 
413  static void
414  applyJacobianTransformationToShapeFunctionsDerivatives( int const q,
415  real64 const ( &invJ )[3][3],
416  real64 ( &gradN )[numNodes][3] );
417 
418 };
419 
421 
423 inline
424 void
425 H1_Pyramid_Lagrange1_Gauss5_impl::
426  jacobianTransformation( int const q,
427  real64 const (&X)[numNodes][3],
428  real64 ( & J )[3][3] )
429 {
430  real64 const quadratureCoords[3] = { quadratureParentCoords0( q ),
431  quadratureParentCoords1( q ),
432  quadratureParentCoords2( q ) };
433 
434  real64 const psi0[2] = { 0.5 - 0.5*quadratureCoords[0],
435  0.5 + 0.5*quadratureCoords[0] };
436  real64 const psi1[2] = { 0.5 - 0.5*quadratureCoords[1],
437  0.5 + 0.5*quadratureCoords[1] };
438  real64 const psi2 = 0.5 - 0.5*quadratureCoords[2];
439  constexpr real64 dpsi[2] = { -0.5, 0.5 };
440 
441  // Contributions from basis functions paired with base nodes
442  for( localIndex a=0; a<2; ++a )
443  {
444  for( localIndex b=0; b<2; ++b )
445  {
446  real64 const dNdXi[3] = { dpsi[a] * psi1[b] * psi2,
447  psi0[a] * dpsi[b] * psi2,
448  psi0[a] * psi1[b] * dpsi[0] };
449  localIndex const nodeIndex = linearMap( a, b );
450  for( int i = 0; i < 3; ++i )
451  {
452  for( int j = 0; j < 3; ++j )
453  {
454  J[i][j] = J[i][j] + dNdXi[ j ] * X[nodeIndex][i];
455  }
456  }
457  }
458  }
459 
460  // Contribution from the basis function paired with the apex nodes
461  for( int i = 0; i < 3; ++i )
462  {
463  J[i][2] = J[i][2] + dpsi[1] * X[4][i];
464  }
465 }
466 
467 //*************************************************************************************************
468 
470 inline
471 void
472 H1_Pyramid_Lagrange1_Gauss5_impl::
473  applyJacobianTransformationToShapeFunctionsDerivatives( int const q,
474  real64 const ( &invJ )[3][3],
475  real64 (& gradN)[numNodes][3] )
476 {
477  real64 const quadratureCoords[3] = { quadratureParentCoords0( q ),
478  quadratureParentCoords1( q ),
479  quadratureParentCoords2( q ) };
480 
481  real64 const psi0[2] = { 0.5*( 1.0 - quadratureCoords[0] ),
482  0.5*( 1.0 + quadratureCoords[0] ) };
483  real64 const psi1[2] = { 0.5*( 1.0 - quadratureCoords[1] ),
484  0.5*( 1.0 + quadratureCoords[1] ) };
485  real64 const psi2 = 0.5*( 1.0 - quadratureCoords[2]);
486  constexpr real64 dpsi[2] = { -0.5, 0.5 };
487 
488  // Contributions from basis functions paired with base nodes
489  for( localIndex a=0; a<2; ++a )
490  {
491  for( localIndex b=0; b<2; ++b )
492  {
493  real64 const dNdXi[3] = { dpsi[a] * psi1[b] * psi2,
494  psi0[a] * dpsi[b] * psi2,
495  psi0[a] * psi1[b] * dpsi[0] };
496  localIndex const nodeIndex = linearMap( a, b );
497  for( int i = 0; i < 3; ++i )
498  {
499  gradN[nodeIndex][i] = 0.0;
500  for( int j = 0; j < 3; ++j )
501  {
502  gradN[nodeIndex][i] = gradN[nodeIndex][i] + dNdXi[ j ] * invJ[j][i];
503  }
504  }
505  }
506  }
507 
508  // Contribution from the basis function paired with the apex nodes
509  for( int i = 0; i < 3; ++i )
510  {
511  gradN[4][i] = dpsi[1] * invJ[2][i];
512  }
513 }
514 
515 //*************************************************************************************************
516 
518 inline
519 void
521  calcN( real64 const ( &pointCoord )[3],
522  real64 ( & N )[numNodes] )
523 {
524  N[0] = 0.125*( 1.0 - pointCoord[0] ) * ( 1.0 - pointCoord[1] ) * ( 1.0 - pointCoord[2] );
525  N[1] = 0.125*( 1.0 + pointCoord[0] ) * ( 1.0 - pointCoord[1] ) * ( 1.0 - pointCoord[2] );
526  N[2] = 0.125*( 1.0 - pointCoord[0] ) * ( 1.0 + pointCoord[1] ) * ( 1.0 - pointCoord[2] );
527  N[3] = 0.125*( 1.0 + pointCoord[0] ) * ( 1.0 + pointCoord[1] ) * ( 1.0 - pointCoord[2] );
528  N[4] = 0.5*( 1.0 + pointCoord[2] );
529 }
530 
532 inline
533 void
535  calcN( localIndex const q,
536  real64 ( & N )[numNodes] )
537 {
538  real64 const xi[3] = { quadratureParentCoords0( q ),
539  quadratureParentCoords1( q ),
540  quadratureParentCoords2( q ) };
541 
542  calcN( xi, N );
543 }
544 
546 inline
548  calcN( localIndex const q,
549  StackVariables const & GEOS_UNUSED_PARAM( stack ),
550  real64 ( & N )[numNodes] )
551 {
552  return calcN( q, N );
553 }
554 
555 //*************************************************************************************************
556 
559 real64
561  real64 const (&X)[numNodes][3],
562  real64 (& J)[3][3] )
563 {
564  for( int i = 0; i < 3; ++i )
565  {
566  for( int j = 0; j < 3; ++j )
567  {
568  J[i][j] = 0;
569  }
570  }
571  jacobianTransformation( q, X, J );
572  real64 const detJ = LvArray::tensorOps::determinant< 3 >( J );
573  return detJ * quadratureWeight( q );
574 }
575 
578 real64
580  real64 const (&X)[numNodes][3],
581  StackVariables const & GEOS_UNUSED_PARAM( stack ),
582  real64 (& J)[3][3] )
583 {
584  return calcJacobian( q, X, J );
585 }
586 
588 inline
590  real64 const (&X)[numNodes][3],
591  real64 (& gradN)[numNodes][3] )
592 {
593  real64 J[3][3] = {{0}};
594 
595  jacobianTransformation( q, X, J );
596 
597  real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
598 
599  applyJacobianTransformationToShapeFunctionsDerivatives( q, J, gradN );
600 
601  return detJ * quadratureWeight( q );
602 }
603 
605 inline
607  calcGradN( localIndex const q,
608  real64 const (&X)[numNodes][3],
609  StackVariables const & GEOS_UNUSED_PARAM( stack ),
610  real64 ( & gradN )[numNodes][3] )
611 {
612  return calcGradN( q, X, gradN );
613 }
614 
616 inline
617 real64
619  real64 const (&X)[numNodes][3],
620  real64 (& gradN)[numFaces][3] )
621 {
622  GEOS_UNUSED_VAR( q, X, gradN );
623  GEOS_ERROR( "Unsupported bubble functions for pyramid elements" );
624  return 0.0;
625 }
626 
627 //*************************************************************************************************
628 
630 inline
631 real64
634  real64 const (&X)[numNodes][3] )
635 {
636  real64 J[3][3] = {{0}};
637 
638  jacobianTransformation( q, X, J );
639 
640  return LvArray::tensorOps::determinant< 3 >( J ) * quadratureWeight( q );
641 }
642 
644 
647  public FiniteElementBase
648 {
649 public:
650 
653 
656 
657 
662  {}
663 
664  virtual ~H1_Pyramid_Lagrange1_Gauss5() override final = default;
665 
671  {
672  return static_cast< H1_Pyramid_Lagrange1_Gauss5_impl * >(this);
673  }
674 
680  {
681  return static_cast< H1_Pyramid_Lagrange1_Gauss5_impl const * >(this);
682  }
683 
684 };
685 
686 }
687 }
688 #endif //GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_H1PYRAMIDLAGRANGE1GAUSS5_HPP_
#define GEOS_HOST_DEVICE
Marks a host-device function.
Definition: GeosxMacros.hpp:49
#define GEOS_UNUSED_VAR(...)
Mark an unused variable and silence compiler warnings.
Definition: GeosxMacros.hpp:84
#define GEOS_FORCE_INLINE
Marks a function or lambda for inlining.
Definition: GeosxMacros.hpp:51
#define GEOS_UNUSED_PARAM(X)
Mark an unused argument and silence compiler warnings.
Definition: GeosxMacros.hpp:72
#define GEOS_ERROR(...)
Raise a hard error and terminate the program.
Definition: Logger.hpp:204
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.
constexpr static localIndex numFaces
The number of faces per element.
GEOS_HOST_DEVICE FiniteElementBase_impl & operator=(FiniteElementBase_impl const &)=default
Default copy assignment operator.
Base class for FEM element implementations.
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.
static GEOS_HOST_DEVICE void calcFaceBubbleN(localIndex const q, real64(&N)[numFaces])
Calculate shape functions values for each support face at a quadrature point.
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.
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.
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.
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 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 calcFaceBubbleN(real64 const (&pointCoord)[3], real64(&N)[numFaces])
Calculate shape functions values for each support face at a given point in the parent space.
static GEOS_HOST_DEVICE real64 calcGradFaceBubbleN(localIndex const q, real64 const (&X)[numNodes][3], real64(&gradN)[numFaces][3])
Calculate the shape bubble function derivatives wrt the physical coordinates.
DO_NOT_DOCUMENT GEOS_HOST_DEVICE static GEOS_FORCE_INLINE void calcN(real64 const (&pointCoord)[3], real64(&N)[numNodes])
Calculate shape functions values at a single point.
static GEOS_HOST_DEVICE real64 transformedQuadratureWeight(localIndex const q, real64 const (&X)[numNodes][3])
Calculate the integration weights for a quadrature point.
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.
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.
H1_Pyramid_Lagrange1_Gauss5_impl * getImpl()
Get the device-compatible implementation type.
H1_Pyramid_Lagrange1_Gauss5_impl const * getImpl() const
Get the device-compatible implementation type.
double real64
64-bit floating point type.
Definition: DataTypes.hpp:98
GEOS_LOCALINDEX_TYPE localIndex
Local index type (for indexing objects within an MPI partition).
Definition: DataTypes.hpp:84
Kernel variables (dof numbers, jacobian and residual) located on the stack.