GEOS
H1_Wedge_Lagrange1_Gauss6.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_H1WEDGELAGRANGE1GAUSS6_HPP_
21 #define GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_H1WEDGELAGRANGE1GAUSS6_HPP_
22 
23 #include "FiniteElementBase.hpp"
24 #include "LagrangeBasis1.hpp"
25 
26 
27 namespace geos
28 {
29 namespace finiteElement
30 {
31 
56 {
57 public:
58 
61 
64 
66  using StackVariables = typename Base::StackVariables;
67 
69  template< typename SubregionType >
70  using MeshData = typename Base::template MeshData< SubregionType >;
71 
74  ~H1_Wedge_Lagrange1_Gauss6_impl() = default;
80 
88  {
89  GEOS_UNUSED_VAR( stack );
90  return numQuadraturePoints;
91  }
92 
100  {
101  GEOS_UNUSED_VAR( stack );
102  return numNodes;
103  }
104 
113  static void getSamplingPointCoordInParentSpace( int const & linearIndex,
114  real64 (& samplingPointCoord)[3] )
115  {
116  int const i0 = linearIndex % numSamplingPointsPerDirection;
117  int const i1 = ( (linearIndex - i0)/numSamplingPointsPerDirection ) % numSamplingPointsPerDirection;
118  int const i2 = ( (linearIndex - i0)/numSamplingPointsPerDirection - i1 ) / numSamplingPointsPerDirection;
119 
120  real64 const step = 1. / ( numSamplingPointsPerDirection - 1 );
121 
122  real64 const r = i0 * step;
123  real64 const s = i1 * step;
124  real64 const t = i2 * 2 * step;
125  if( (r+s) <= 1 )
126  {
127  samplingPointCoord[0] = r;
128  samplingPointCoord[1] = s;
129  samplingPointCoord[2] = t;
130  }
131  else
132  {
133  // if outside of the triangle need to reproject it. Points will be doubled though.
134  samplingPointCoord[0] = 1 - r;
135  samplingPointCoord[1] = 1 - s;
136  samplingPointCoord[2] = t;
137  }
138  }
139 
146  inline
147  static void calcN( real64 const (&coords)[3],
148  real64 ( &N )[numNodes] );
149 
150 
159  static void calcN( localIndex const q,
160  real64 ( &N )[numNodes] );
161 
171  inline
172  static void calcN( localIndex const q,
173  StackVariables const & stack,
174  real64 ( &N )[numNodes] );
175 
185  static void calcFaceBubbleN( real64 const (&pointCoord)[3],
186  real64 (& N)[numFaces] )
187  {
188 
189  real64 const r = pointCoord[0];
190  real64 const s = pointCoord[1];
191  real64 const xi = pointCoord[2];
192 
193  N[0] = 4.0 * (1.0 - r - s) * s * LagrangeBasis1::valueBubble( xi );
194  N[1] = 4.0 * (1.0 - r - s) * r * LagrangeBasis1::valueBubble( xi );
195  N[2] = (1.0 - r - s) * r * s * LagrangeBasis1::value( 0, xi );
196  N[3] = (1.0 - r - s) * r * s * LagrangeBasis1::value( 1, xi );
197  N[4] = 4.0 * r * s * LagrangeBasis1::valueBubble( xi );
198 
199  }
200 
209  inline
210  static void calcFaceBubbleN( localIndex const q,
211  real64 (& N)[numFaces] )
212  {
213 
214  real64 const pointCoord[3] = {quadratureParentCoords0( q ),
215  quadratureParentCoords1( q ),
216  quadratureParentCoords2( q )};
217 
218  calcFaceBubbleN( pointCoord, N );
219  }
220 
230  static
232  real64 const (&X)[numNodes][3],
233  real64 ( &J )[3][3] );
234 
245  static
247  real64 const (&X)[numNodes][3],
248  StackVariables const &stack,
249  real64 ( &J )[3][3] );
250 
261  static real64 calcGradN( localIndex const q,
262  real64 const (&X)[numNodes][3],
263  real64 ( &gradN )[numNodes][3] );
264 
276  inline
277  static real64 calcGradN( localIndex const q,
278  real64 const (&X)[numNodes][3],
279  StackVariables const & stack,
280  real64 ( &gradN )[numNodes][3] );
281 
293  real64 const (&X)[numNodes][3],
294  real64 ( &gradN )[numFaces][3] );
295 
305  real64 const (&X)[numNodes][3] );
306 
317  real64 const (&X)[numNodes][3],
318  StackVariables const & stack )
319  { GEOS_UNUSED_VAR( stack ); return transformedQuadratureWeight( q, X ); }
320 
330  static real64 invJacobianTransformation( int const q,
331  real64 const (&X)[numNodes][3],
332  real64 ( & J )[3][3] )
333  {
334  jacobianTransformation( q, X, J );
335  return LvArray::tensorOps::invert< 3 >( J );
336  }
337 
338 
339 private:
341  constexpr static real64 parentVolume = 1.0;
342 
344  constexpr static real64 weight = parentVolume / numQuadraturePoints;
345 
348  constexpr static real64 quadratureCrossSectionCoord = 1.0 / 6.0;
349 
353  constexpr static real64 quadratureLongitudinalCoord = 1.0 / 1.732050807568877293528;
354 
362  template< typename T >
364  inline
365  constexpr static T linearMap( T const indexT, T const indexL )
366  {
367  return 2 * indexT + indexL;
368  }
369 
377  inline
378  constexpr static real64 parentCoords0( localIndex const a )
379  {
380  return 0.5 * ( a & 2 );
381  }
382 
390  inline
391  constexpr static real64 parentCoords1( localIndex const a )
392  {
393  return 0.25 * ( a & 4 );
394  }
395 
403  inline
404  constexpr static real64 parentCoords2( localIndex const a )
405  {
406  return -1.0 + 2 * ( a & 1 );
407  }
408 
416  inline
417  constexpr static real64 quadratureParentCoords0( localIndex const q )
418  {
419  return quadratureCrossSectionCoord + 0.5 * parentCoords0( q );
420  }
421 
429  inline
430  constexpr static real64 quadratureParentCoords1( localIndex const q )
431  {
432  return quadratureCrossSectionCoord + 0.5 * parentCoords1( q );
433  }
434 
442  inline
443  constexpr static real64 quadratureParentCoords2( localIndex const q )
444  {
445  return parentCoords2( q ) * quadratureLongitudinalCoord;
446  }
447 
455  static void jacobianTransformation( int const q,
456  real64 const (&X)[numNodes][3],
457  real64 ( &J )[3][3] );
458 
469  static void
470  applyJacobianTransformationToShapeFunctionsDerivatives( int const q,
471  real64 const ( &invJ )[3][3],
472  real64 ( &gradN )[numNodes][3] );
473 
474 };
475 
477 
479 inline
480 void
481 H1_Wedge_Lagrange1_Gauss6_impl::
482  jacobianTransformation( int const q,
483  real64 const (&X)[numNodes][3],
484  real64 ( & J )[3][3] )
485 {
486  real64 const r = quadratureParentCoords0( q );
487  real64 const s = quadratureParentCoords1( q );
488  real64 const xi = quadratureParentCoords2( q );
489 
490  real64 const psiTRI[3] = { 1.0 - r - s, r, s };
491  real64 const psiLIN[2] = { 0.5 - 0.5*xi, 0.5 + 0.5*xi };
492  constexpr real64 dpsiTRI[2][3] = { { -1.0, 1.0, 0.0 }, { -1.0, 0.0, 1.0 } };
493  constexpr real64 dpsiLIN[2] = { -0.5, 0.5 };
494 
495  for( localIndex a=0; a<3; ++a )
496  {
497  for( localIndex b=0; b<2; ++b )
498  {
499  real64 const dNdXi[3] = { dpsiTRI[0][a] * psiLIN[b],
500  dpsiTRI[1][a] * psiLIN[b],
501  psiTRI[a] * dpsiLIN[b] };
502  localIndex const nodeIndex = linearMap( a, b );
503  for( int i = 0; i < 3; ++i )
504  {
505  for( int j = 0; j < 3; ++j )
506  {
507  J[i][j] = J[i][j] + dNdXi[ j ] * X[nodeIndex][i];
508  }
509  }
510  }
511  }
512 }
513 
514 //*************************************************************************************************
515 
517 inline
518 void
519 H1_Wedge_Lagrange1_Gauss6_impl::
520  applyJacobianTransformationToShapeFunctionsDerivatives( int const q,
521  real64 const ( &invJ )[3][3],
522  real64 (& gradN)[numNodes][3] )
523 {
524  real64 const r = quadratureParentCoords0( q );
525  real64 const s = quadratureParentCoords1( q );
526  real64 const xi = quadratureParentCoords2( q );
527 
528  real64 const psiTRI[3] = { 1.0 - r - s, r, s };
529  real64 const psiLIN[2] = { 0.5 - 0.5*xi, 0.5 + 0.5*xi };
530  constexpr real64 dpsiTRI[2][3] = { { -1.0, 1.0, 0.0 }, { -1.0, 0.0, 1.0 } };
531  constexpr real64 dpsiLIN[2] = { -0.5, 0.5 };
532 
533  for( localIndex a=0; a<3; ++a )
534  {
535  for( localIndex b=0; b<2; ++b )
536  {
537  real64 const dNdXi[3] = { dpsiTRI[0][a] * psiLIN[b],
538  dpsiTRI[1][a] * psiLIN[b],
539  psiTRI[a] * dpsiLIN[b] };
540  localIndex const nodeIndex = linearMap( a, b );
541  for( int i = 0; i < 3; ++i )
542  {
543  gradN[nodeIndex][i] = 0.0;
544  for( int j = 0; j < 3; ++j )
545  {
546  gradN[nodeIndex][i] = gradN[nodeIndex][i] + dNdXi[ j ] * invJ[j][i];
547  }
548  }
549  }
550  }
551 }
552 
553 //*************************************************************************************************
554 
556 inline
557 void
559  real64 (& N)[numNodes] )
560 {
561  real64 const r = coords[0];
562  real64 const s = coords[1];
563  real64 const xi = coords[2];
564 
565  N[0] = 0.5*( 1.0 - r - s ) * ( 1.0 - xi );
566  N[1] = 0.5*( 1.0 - r - s ) * ( 1.0 + xi );
567  N[2] = 0.5* r * ( 1.0 - xi );
568  N[3] = 0.5* r * ( 1.0 + xi );
569  N[4] = 0.5* s * ( 1.0 - xi );
570  N[5] = 0.5* s * ( 1.0 + xi );
571 
572 }
573 
574 
576 inline
577 void
579  calcN( localIndex const q,
580  real64 (& N)[numNodes] )
581 {
582  real64 const pointCoord[3] = {quadratureParentCoords0( q ),
583  quadratureParentCoords1( q ),
584  quadratureParentCoords2( q )};
585 
586  calcN( pointCoord, N );
587 }
588 
590 inline
592  calcN( localIndex const q,
593  StackVariables const & GEOS_UNUSED_PARAM( stack ),
594  real64 ( & N )[numNodes] )
595 {
596  return calcN( q, N );
597 }
598 
599 //*************************************************************************************************
600 
603 real64
605  real64 const (&X)[numNodes][3],
606  real64 (& J)[3][3] )
607 {
608  for( int i = 0; i < 3; ++i )
609  {
610  for( int j = 0; j < 3; ++j )
611  {
612  J[i][j] = 0;
613  }
614  }
615  jacobianTransformation( q, X, J );
616  real64 const detJ = LvArray::tensorOps::determinant< 3 >( J );
617  return detJ * weight;
618 }
619 
622 real64
624  real64 const (&X)[numNodes][3],
625  StackVariables const & GEOS_UNUSED_PARAM( stack ),
626  real64 (& J)[3][3] )
627 {
628  return calcJacobian( q, X, J );
629 }
630 
632 inline
633 real64
635  calcGradN( localIndex const q,
636  real64 const (&X)[numNodes][3],
637  real64 (& gradN)[numNodes][3] )
638 {
639  real64 J[3][3] = {{0}};
640 
641  jacobianTransformation( q, X, J );
642 
643  real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
644 
645  applyJacobianTransformationToShapeFunctionsDerivatives( q, J, gradN );
646 
647  return detJ * weight;
648 }
649 
651 inline
653  calcGradN( localIndex const q,
654  real64 const (&X)[numNodes][3],
655  StackVariables const & GEOS_UNUSED_PARAM( stack ),
656  real64 ( & gradN )[numNodes][3] )
657 {
658  return calcGradN( q, X, gradN );
659 }
660 
662 inline
663 real64
665  real64 const (&X)[numNodes][3],
666  real64 (& gradN)[numFaces][3] )
667 {
668 
669  real64 J[3][3] = {{0}};
670 
671  jacobianTransformation( q, X, J );
672 
673  real64 const detJ = LvArray::tensorOps::invert< 3 >( J );
674 
675  real64 dNdXi[numFaces][3] = {{0}};
676 
677  real64 const r = quadratureParentCoords0( q );
678  real64 const s = quadratureParentCoords1( q );
679  real64 const xi = quadratureParentCoords2( q );
680 
681  dNdXi[0][0] = -4.0 * s * LagrangeBasis1::valueBubble( xi ); // dN0/dr
682  dNdXi[0][1] = 4.0 * (1.0 - r - 2.0 * s) * LagrangeBasis1::valueBubble( xi ); // dN0/ds
683  dNdXi[0][2] = 4.0 *(1 - r - s) * s * LagrangeBasis1::gradientBubble( xi ); // dN0/dxi
684 
685  dNdXi[1][0] = 4.0 * (1.0 - 2.0 * r - s) * LagrangeBasis1::valueBubble( xi ); // dN1/dr
686  dNdXi[1][1] = -4.0 * r * LagrangeBasis1::valueBubble( xi ); // dN1/ds
687  dNdXi[1][2] = 4.0 * (1 - r - s) * r * LagrangeBasis1::gradientBubble( xi ); // dN1/dxi
688 
689  dNdXi[2][0] = (1.0 - 2.0 * r - s) * s * LagrangeBasis1::value( 0, xi ); // dN2/dr
690  dNdXi[2][1] = (1.0 - r - 2.0 * s) * r * LagrangeBasis1::value( 0, xi ); // dN2/ds
691  dNdXi[2][2] = (1 - r - s) * r * s * LagrangeBasis1::gradient( 0, xi ); // dN2/dxi
692 
693  dNdXi[3][0] = (1.0 - 2.0 * r - s) * s * LagrangeBasis1::value( 1, xi ); // dN3/dr
694  dNdXi[3][1] = (1.0 - r - 2.0 * s) * r * LagrangeBasis1::value( 1, xi ); // dN3/ds
695  dNdXi[3][2] = (1 - r - s) * r * s * LagrangeBasis1::gradient( 1, xi ); // dN3/dxi
696 
697  dNdXi[4][0] = 4.0 * s * LagrangeBasis1::valueBubble( xi ); // dN4/dr
698  dNdXi[4][1] = 4.0 * r * LagrangeBasis1::valueBubble( xi ); // dN4/ds
699  dNdXi[4][2] = 4.0 * r * s * LagrangeBasis1::gradientBubble( xi ); // dN4/dxi
700 
701  for( int fi=0; fi<numFaces; ++fi )
702  {
703  gradN[fi][0] = dNdXi[fi][0] * J[0][0] + dNdXi[fi][1] * J[1][0] + dNdXi[fi][2] * J[2][0];
704  gradN[fi][1] = dNdXi[fi][0] * J[0][1] + dNdXi[fi][1] * J[1][1] + dNdXi[fi][2] * J[2][1];
705  gradN[fi][2] = dNdXi[fi][0] * J[0][2] + dNdXi[fi][1] * J[1][2] + dNdXi[fi][2] * J[2][2];
706  }
707 
708  return detJ * weight;
709 }
710 
711 //*************************************************************************************************
712 
714 inline
715 real64
718  real64 const (&X)[numNodes][3] )
719 {
720  real64 J[3][3] = {{0}};
721 
722  jacobianTransformation( q, X, J );
723 
724  return LvArray::tensorOps::determinant< 3 >( J ) * weight;
725 }
726 
728 
731  public FiniteElementBase
732 {
733 
734 public:
735 
738 
741  {}
742 
748  {
749  return static_cast< H1_Wedge_Lagrange1_Gauss6_impl * >(this);
750  }
751 
757  {
758  return static_cast< H1_Wedge_Lagrange1_Gauss6_impl const * >(this);
759  }
760 
761 };
762 
763 }
764 }
765 
766 #endif //GEOS_FINITEELEMENT_ELEMENTFORMULATIONS_H1WEDGELAGRANGE1GAUSS6_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
Device-compatible (non virtual) Base class for all finite element formulations.
constexpr static localIndex numQuadraturePoints
The number of quadrature points per element.
constexpr static int numSamplingPointsPerDirection
Number of sampling points.
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.
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.
DO_NOT_DOCUMENT static GEOS_HOST_DEVICE localIndex getNumQuadraturePoints(StackVariables const &stack)
Get the number of quadrature points.
static GEOS_HOST_DEVICE void calcN(localIndex const q, 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 real64 calcGradFaceBubbleN(localIndex const q, real64 const (&X)[numNodes][3], real64(&gradN)[numFaces][3])
Calculate the shape bubble function derivatives wrt the physical coordinates.
static GEOS_HOST_DEVICE 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 real64 calcJacobian(localIndex const q, real64 const (&X)[numNodes][3], real64(&J)[3][3])
Calculate the Jacobian matrix 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.
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 localIndex getNumSupportPoints(StackVariables const &stack)
Get the number of support points.
static GEOS_HOST_DEVICE void calcFaceBubbleN(localIndex const q, real64(&N)[numFaces])
Calculate face bubble functions values for each face at a quadrature point.
typename Base::template MeshData< SubregionType > MeshData
Mesh data structure for the 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 shape functions values for each support face at a given point in the parent space.
static GEOS_HOST_DEVICE void calcN(real64 const (&coords)[3], real64(&N)[numNodes])
Calculate shape functions values at a single 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 calcGradN(localIndex const q, real64 const (&X)[numNodes][3], real64(&gradN)[numNodes][3])
Calculate the shape functions derivatives wrt the physical coordinates.
H1_Wedge_Lagrange1_Gauss6_impl * getImpl()
Get the device-compatible implementation type.
H1_Wedge_Lagrange1_Gauss6_impl const * getImpl() const
Get the device-compatible implementation type.
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE real64 gradientBubble(const real64 xi)
The gradient of the bubble basis function for support point 1 evaluated at a point along the axes.
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE real64 valueBubble(const real64 xi)
The value of the bubble basis function.
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE real64 gradient(const int index, const real64 xi)
The gradient of the basis function for a support point evaluated at a point along the axes.
GEOS_HOST_DEVICE constexpr static GEOS_FORCE_INLINE real64 value(const int index, const real64 xi)
The value of the basis function for a support point evaluated at a point along the axes.
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.