Skip to main content

GetGlobalElemShapeData

The GetGlobalElemShapeData method computes the global element shape function data (including shape functions, their derivatives, and related information) for a specified element. This method takes the local element shape function data and transforms it to the global coordinate system using the nodal coordinates provided in xij.

Interface

INTERFACE
MODULE SUBROUTINE GetGlobalElemShapeData(obj, globalElement, elemsd, &
xij, geoElemsd, islocal)
CLASS(FEDOF_), INTENT(INOUT) :: obj
!! Abstract finite element
INTEGER(I4B), INTENT(IN) :: globalElement
!! shape function data
TYPE(ElemshapeData_), INTENT(INOUT) :: elemsd
!! global element shape data
REAL(DFP), INTENT(IN) :: xij(:, :)
!! nodal coordinates of element
!! The number of rows in xij should be same as the spatial dimension
!! The number of columns should be same as the number of nodes
!! present in the reference element in geoElemsd.
TYPE(ElemShapeData_), OPTIONAL, INTENT(INOUT) :: geoElemsd
!! shape function data for geometry which contains local shape function
!! data. If not present then the local shape function in elemsd
!! will be used for geometry. This means we are dealing with
!! isoparametric shape functions.
LOGICAL(LGT), OPTIONAL, INTENT(IN) :: islocal
!! if true then the global element is a local element
END SUBROUTINE GetGlobalElemShapeData
END INTERFACE

Parameters

ParameterTypeIntentDescription
objCLASS(FEDOF_)INTENT(INOUT)The FEDOF object instance
globalElementINTEGER(I4B)INTENT(IN)The global element number for which to compute shape function data
elemsdTYPE(ElemshapeData_)INTENT(INOUT)Output variable that will contain the global element shape data
xijREAL(DFP)INTENT(IN)Nodal coordinates of the element. The number of rows in xij should match the spatial dimension, and the number of columns should match the number of nodes in the reference element
geoElemsdTYPE(ElemShapeData_)OPTIONAL, INTENT(INOUT)Shape function data for geometry which contains local shape function data. If not present, the local shape function in elemsd will be used for geometry (isoparametric case)
islocalLOGICAL(LGT)OPTIONAL, INTENT(IN)If true, globalElement is treated as a local element number rather than a global element number

Implementation Details

The method performs the following operations:

  1. Obtains the element topology index for the specified element
  2. Performs error checking in debug mode to ensure the element topology index is valid and the finite element pointer is associated
  3. Delegates the actual computation to the appropriate finite element object's GetGlobalElemShapeData method

Usage Example

TYPE(FEDOF_) :: myFEDOF
TYPE(ElemshapeData_) :: elemsd
REAL(DFP), ALLOCATABLE :: xij(:, :)
INTEGER(I4B) :: elemNum

! Initialize myFEDOF and prepare xij with nodal coordinates
! ...

! Get the global element shape data
CALL myFEDOF%GetGlobalElemShapeData(globalElement=elemNum, elemsd=elemsd, xij=xij)

! Now elemsd contains the shape functions and derivatives in the global coordinate system

Notes

  • This method is part of the core functionality for finite element computations, as it provides the necessary information for evaluating functions and their derivatives in the global coordinate system.
  • The transformation from local to global coordinates is handled internally by the finite element implementation.
  • If geoElemsd is not provided, the method will use an isoparametric formulation where the same shape functions are used for both the solution field and the geometry.
  • Debug mode provides additional error checking to ensure the element topology index is valid and required pointers are associated.

Would you like additional information or clarification about any aspect of this method?

Example 1

!> author: Vikas Sharma, Ph. D.
! date: 2025-06-09
! summary: This program tests the GetLocalElemshapeData
! method of the FEDOF class.

PROGRAM main
USE FEDOF_Class
USE FEDomain_Class
USE AbstractMesh_Class
USE HDF5File_Class
USE Display_Method
USE GlobalData
USE Test_Method
USE ExceptionHandler_Class, ONLY: e, EXCEPTION_INFORMATION
USE BaseType, ONLY: QuadraturePoint_, TypeQuadratureOpt, ElemshapeData_
USE QuadraturePoint_Method
USE ElemshapeData_Method
USE ApproxUtility

IMPLICIT NONE

TYPE(FEDOF_) :: obj, geoobj
TYPE(FEDomain_) :: dom
CLASS(AbstractMesh_), POINTER :: meshptr => NULL()
CHARACTER(*), PARAMETER :: &
filename = "../../FEMesh/examples/meshdata/small_tri3_mesh.h5", &
baseContinuity = "H1", &
baseInterpolation = "Heirarchical", &
testname = baseContinuity//" "//baseInterpolation//" GetLocalElemshapeData "

TYPE(HDF5File_) :: meshfile

TYPE(QuadraturePoint_) :: quad

TYPE(ElemshapeData_) :: elemsd, geoelemsd

INTEGER(I4B) :: globalElement, telements, order, &
nodecon(100), ii, jj, nsd

REAL(DFP) :: nodecoord(3, 100)

LOGICAL(LGT) :: islocal, isok

CALL e%setQuietMode(EXCEPTION_INFORMATION, .TRUE.)
CALL meshfile%Initiate(filename, mode="READ")
CALL meshfile%OPEN()
CALL dom%Initiate(meshfile, '')
meshptr => dom%GetMeshPointer()
nsd = meshptr%GetNSD()

CALL test1
CALL test2
CALL test3

CALL dom%DEALLOCATE()
CALL meshfile%DEALLOCATE()

CONTAINS

!----------------------------------------------------------------------------
! test1
!----------------------------------------------------------------------------

SUBROUTINE test1

REAL(DFP) :: found(1), want(1)

order = 1
CALL obj%Initiate(baseContinuity=baseContinuity, &
baseInterpolation=baseInterpolation, &
order=order, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

globalElement = 1; islocal = .TRUE.
CALL obj%GetQuadraturePoints(quad=quad, globalElement=globalElement, &
quadratureType=TypeQuadratureOpt%GaussLegendre, &
order=order, islocal=islocal)

CALL obj%GetLocalElemshapeData(quad=quad, elemsd=elemsd, &
globalElement=globalElement, islocal=islocal)

CALL meshptr%GetNodeCoord(nodecoord=nodecoord, nrow=ii, ncol=jj, &
globalElement=globalElement, islocal=islocal)

CALL obj%GetGlobalElemshapeData(elemsd=elemsd, xij=nodecoord(1:nsd, 1:jj), &
globalElement=globalElement, islocal=islocal)

found = SUM(elemsd%N, dim=1)
want = 1.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

found(1) = SUM(elemsd%dNdXi(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

found(1) = SUM(elemsd%dNdXi(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

found(1) = SUM(elemsd%dNdXt(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

found(1) = SUM(elemsd%dNdXt(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

END SUBROUTINE test1

!----------------------------------------------------------------------------
! test2
!----------------------------------------------------------------------------

SUBROUTINE test2

REAL(DFP) :: found(1), want(1)

order = 2
CALL obj%Initiate(baseContinuity=baseContinuity, &
baseInterpolation=baseInterpolation, &
order=order, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

CALL geoobj%Initiate(baseContinuity="H1", &
baseInterpolation="Lagrange", &
order=1, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

globalElement = 1; islocal = .TRUE.
CALL obj%GetQuadraturePoints(quad=quad, globalElement=globalElement, &
quadratureType=TypeQuadratureOpt%GaussLegendre, &
order=1, islocal=islocal)

CALL obj%GetLocalElemshapeData(quad=quad, elemsd=elemsd, &
globalElement=globalElement, islocal=islocal)

CALL geoobj%GetLocalElemshapeData(quad=quad, elemsd=geoelemsd, &
globalElement=globalElement, islocal=islocal)

CALL meshptr%GetNodeCoord(nodecoord=nodecoord, nrow=ii, ncol=jj, &
globalElement=globalElement, islocal=islocal)

CALL obj%GetGlobalElemshapeData(elemsd=elemsd, xij=nodecoord(1:nsd, 1:jj), &
globalElement=globalElement, islocal=islocal, &
geoelemsd=geoelemsd)

found = SUM(elemsd%N(1:3, :), dim=1)
want = 1.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%N")

found(1) = SUM(elemsd%dNdXi(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%dNdXi")

found(1) = SUM(elemsd%dNdXi(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%dNdXi")

found(1) = SUM(elemsd%dNdXt(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%dNdXt")

found(1) = SUM(elemsd%dNdXt(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%dNdXt")

END SUBROUTINE test2

!----------------------------------------------------------------------------
! test3
!----------------------------------------------------------------------------

SUBROUTINE test3

REAL(DFP) :: found(1), want(1)

order = 3
CALL obj%Initiate(baseContinuity=baseContinuity, &
baseInterpolation=baseInterpolation, &
order=order, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

CALL geoobj%Initiate(baseContinuity="H1", &
baseInterpolation="Lagrange", &
order=1, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

globalElement = 1; islocal = .TRUE.
CALL obj%GetQuadraturePoints(quad=quad, globalElement=globalElement, &
quadratureType=TypeQuadratureOpt%GaussLegendre, &
order=1, islocal=islocal)

CALL obj%GetLocalElemshapeData(quad=quad, elemsd=elemsd, &
globalElement=globalElement, islocal=islocal)

CALL geoobj%GetLocalElemshapeData(quad=quad, elemsd=geoelemsd, &
globalElement=globalElement, islocal=islocal)

CALL meshptr%GetNodeCoord(nodecoord=nodecoord, nrow=ii, ncol=jj, &
globalElement=globalElement, islocal=islocal)

CALL obj%GetGlobalElemshapeData(elemsd=elemsd, xij=nodecoord(1:nsd, 1:jj), &
globalElement=globalElement, islocal=islocal, &
geoelemsd=geoelemsd)

found = SUM(elemsd%N(1:3, :), dim=1)
want = 1.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%N")

found(1) = SUM(elemsd%dNdXi(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%dNdXi")

found(1) = SUM(elemsd%dNdXi(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%dNdXi")

found(1) = SUM(elemsd%dNdXt(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%dNdXt")

found(1) = SUM(elemsd%dNdXt(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%dNdXt")

END SUBROUTINE test3

!----------------------------------------------------------------------------
!
!----------------------------------------------------------------------------

END PROGRAM main

! total nodes = 25
! total elements = 16
! total faces = 40
! total edges = 0

Example 2

!> author: Vikas Sharma, Ph. D.
! date: 2025-06-09
! summary: This program tests the GetLocalElemshapeData
! method of the FEDOF class.

PROGRAM main
USE FEDOF_Class
USE FEDomain_Class
USE AbstractMesh_Class
USE HDF5File_Class
USE Display_Method
USE GlobalData
USE Test_Method
USE ExceptionHandler_Class, ONLY: e, EXCEPTION_INFORMATION
USE BaseType, ONLY: QuadraturePoint_, TypeQuadratureOpt, ElemshapeData_
USE QuadraturePoint_Method
USE ElemshapeData_Method
USE ApproxUtility

IMPLICIT NONE

TYPE(FEDOF_) :: obj, geoobj
TYPE(FEDomain_) :: dom
CLASS(AbstractMesh_), POINTER :: meshptr => NULL()
CHARACTER(*), PARAMETER :: &
filename = "../../FEMesh/examples/meshdata/small_tri6_mesh.h5", &
baseContinuity = "H1", &
baseInterpolation = "Heirarchical", &
testname = baseContinuity//" "//baseInterpolation//" GetLocalElemshapeData "

TYPE(HDF5File_) :: meshfile

TYPE(QuadraturePoint_) :: quad

TYPE(ElemshapeData_) :: elemsd, geoelemsd

INTEGER(I4B) :: globalElement, telements, order, &
nodecon(100), ii, jj, nsd

REAL(DFP) :: nodecoord(3, 100)

LOGICAL(LGT) :: islocal, isok

CALL e%setQuietMode(EXCEPTION_INFORMATION, .TRUE.)
CALL meshfile%Initiate(filename, mode="READ")
CALL meshfile%OPEN()
CALL dom%Initiate(meshfile, '')
meshptr => dom%GetMeshPointer()
nsd = meshptr%GetNSD()

CALL test1
CALL test2
CALL test3

CALL dom%DEALLOCATE()
CALL meshfile%DEALLOCATE()

CONTAINS

!----------------------------------------------------------------------------
! test1
!----------------------------------------------------------------------------

SUBROUTINE test1

REAL(DFP) :: found(1), want(1)

order = 1
CALL obj%Initiate(baseContinuity=baseContinuity, &
baseInterpolation=baseInterpolation, &
order=order, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

globalElement = 1; islocal = .TRUE.
CALL obj%GetQuadraturePoints(quad=quad, globalElement=globalElement, &
quadratureType=TypeQuadratureOpt%GaussLegendre, &
order=order, islocal=islocal)

CALL obj%GetLocalElemshapeData(quad=quad, elemsd=elemsd, &
globalElement=globalElement, islocal=islocal)

CALL meshptr%GetNodeCoord(nodecoord=nodecoord, nrow=ii, ncol=jj, &
globalElement=globalElement, islocal=islocal)

CALL obj%GetGlobalElemshapeData(elemsd=elemsd, xij=nodecoord(1:nsd, 1:jj), &
globalElement=globalElement, islocal=islocal)

found = SUM(elemsd%N, dim=1)
want = 1.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

found(1) = SUM(elemsd%dNdXi(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

found(1) = SUM(elemsd%dNdXi(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

found(1) = SUM(elemsd%dNdXt(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

found(1) = SUM(elemsd%dNdXt(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname)

END SUBROUTINE test1

!----------------------------------------------------------------------------
! test2
!----------------------------------------------------------------------------

SUBROUTINE test2

REAL(DFP) :: found(1), want(1)

order = 2
CALL obj%Initiate(baseContinuity=baseContinuity, &
baseInterpolation=baseInterpolation, &
order=order, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

CALL geoobj%Initiate(baseContinuity="H1", &
baseInterpolation="Lagrange", &
order=1, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

globalElement = 1; islocal = .TRUE.
CALL obj%GetQuadraturePoints(quad=quad, globalElement=globalElement, &
quadratureType=TypeQuadratureOpt%GaussLegendre, &
order=1, islocal=islocal)

CALL obj%GetLocalElemshapeData(quad=quad, elemsd=elemsd, &
globalElement=globalElement, islocal=islocal)

CALL geoobj%GetLocalElemshapeData(quad=quad, elemsd=geoelemsd, &
globalElement=globalElement, islocal=islocal)

CALL meshptr%GetNodeCoord(nodecoord=nodecoord, nrow=ii, ncol=jj, &
globalElement=globalElement, islocal=islocal)

CALL obj%GetGlobalElemshapeData(elemsd=elemsd, xij=nodecoord(1:nsd, 1:jj), &
globalElement=globalElement, islocal=islocal, &
geoelemsd=geoelemsd)

found = SUM(elemsd%N(1:3, :), dim=1)
want = 1.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%N")

found(1) = SUM(elemsd%dNdXi(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%dNdXi")

found(1) = SUM(elemsd%dNdXi(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%dNdXi")

found(1) = SUM(elemsd%dNdXt(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%dNdXt")

found(1) = SUM(elemsd%dNdXt(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test2 elemsd%dNdXt")

END SUBROUTINE test2

!----------------------------------------------------------------------------
! test3
!----------------------------------------------------------------------------

SUBROUTINE test3

REAL(DFP) :: found(1), want(1)

order = 3
CALL obj%Initiate(baseContinuity=baseContinuity, &
baseInterpolation=baseInterpolation, &
order=order, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

CALL geoobj%Initiate(baseContinuity="H1", &
baseInterpolation="Lagrange", &
order=1, mesh=meshptr, &
ipType=TypeQuadratureOpt%equidistance)

globalElement = 1; islocal = .TRUE.
CALL obj%GetQuadraturePoints(quad=quad, globalElement=globalElement, &
quadratureType=TypeQuadratureOpt%GaussLegendre, &
order=1, islocal=islocal)

CALL obj%GetLocalElemshapeData(quad=quad, elemsd=elemsd, &
globalElement=globalElement, islocal=islocal)

CALL geoobj%GetLocalElemshapeData(quad=quad, elemsd=geoelemsd, &
globalElement=globalElement, islocal=islocal)

CALL meshptr%GetNodeCoord(nodecoord=nodecoord, nrow=ii, ncol=jj, &
globalElement=globalElement, islocal=islocal)

CALL obj%GetGlobalElemshapeData(elemsd=elemsd, xij=nodecoord(1:nsd, 1:jj), &
globalElement=globalElement, islocal=islocal, &
geoelemsd=geoelemsd)

found = SUM(elemsd%N(1:3, :), dim=1)
want = 1.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%N")

found(1) = SUM(elemsd%dNdXi(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%dNdXi")

found(1) = SUM(elemsd%dNdXi(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%dNdXi")

found(1) = SUM(elemsd%dNdXt(:, 1, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%dNdXt")

found(1) = SUM(elemsd%dNdXt(:, 2, 1), dim=1)
want(1) = 0.0_DFP
isok = found(1) .approxeq.want(1)
CALL OK(isok, testname//" test3 elemsd%dNdXt")

END SUBROUTINE test3

!----------------------------------------------------------------------------
!
!----------------------------------------------------------------------------

END PROGRAM main

! total nodes = 25
! total elements = 16
! total faces = 40
! total edges = 0