Nektar++
Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
Nektar::LibUtilities::NodalUtil Class Referenceabstract

A class to assist in the construction of nodal simplex and hybrid elements in two and three dimensions. More...

#include <NodalUtil.h>

Inheritance diagram for Nektar::LibUtilities::NodalUtil:
[legend]

Public Member Functions

virtual ~NodalUtil ()=default
 
NekVector< NekDoubleGetWeights ()
 Obtain the integration weights for the given nodal distribution. More...
 
SharedMatrix GetVandermonde ()
 Return the Vandermonde matrix for the nodal distribution. More...
 
SharedMatrix GetVandermondeForDeriv (size_t dir)
 Return the Vandermonde matrix of the derivative of the basis functions for the nodal distribution. More...
 
SharedMatrix GetDerivMatrix (size_t dir)
 Return the derivative matrix for the nodal distribution. More...
 
SharedMatrix GetInterpolationMatrix (Array< OneD, Array< OneD, NekDouble > > &xi)
 Construct the interpolation matrix used to evaluate the basis at the points xi inside the element. More...
 

Protected Member Functions

 NodalUtil (size_t degree, size_t dim)
 Set up the NodalUtil object. More...
 
virtual NekVector< NekDoublev_OrthoBasis (const size_t mode)=0
 Return the values of the orthogonal basis at the nodal points for a given mode. More...
 
virtual NekVector< NekDoublev_OrthoBasisDeriv (const size_t dir, const size_t mode)=0
 Return the values of the derivative of the orthogonal basis at the nodal points for a given mode. More...
 
virtual std::shared_ptr< NodalUtilv_CreateUtil (Array< OneD, Array< OneD, NekDouble > > &xi)=0
 Construct a NodalUtil object of the appropriate element type for a given set of points. More...
 
virtual NekDouble v_ModeZeroIntegral ()=0
 Return the value of the integral of the zero-th mode for this element. More...
 
virtual size_t v_NumModes ()=0
 Calculate the number of degrees of freedom for this element. More...
 

Protected Attributes

size_t m_dim
 Dimension of the nodal element. More...
 
size_t m_degree
 Degree of the nodal element. More...
 
size_t m_numPoints
 Total number of nodal points. More...
 
Array< OneD, Array< OneD, NekDouble > > m_xi
 Coordinates of the nodal points defining the basis. More...
 

Detailed Description

A class to assist in the construction of nodal simplex and hybrid elements in two and three dimensions.

The NodalUtil class and its subclasses are designed to take care of some common issues that arise when considering triangles, tetrahedra and prismatic elements that are equipped with a nodal Lagrangian basis, defined using a set of nodal points \( \xi_i \) that we store in the array NodalUtil::m_xi. Since one cannot write this basis analytically, we instead construct the Vandermonde matrix

\[ \mathbf{V}_{ij} = \psi_j(\xi_i) \]

where \( \psi_j \) is a basis that spans the polynomial space of the element. The Vandermonde matrix can then be used to construct the integration weights, derivative and interpolation matrices. Although this can be any basis, such as the monomial basis \( x^i y^j z^k \), in practice this is numerically unstable at high polynomial orders. Elements are therefore expected to use the 'traditional' modal orthogonal basis. See Sherwin & Karniadakis or Hesthaven & Warburton for further details of this basis and the surrounding numerical issues.

This class therefore contains the generic logic needed to construct various matrices, and subclasses override virtual functions that define the orthogonal basis and its derivatives for a particular element type.

Definition at line 77 of file NodalUtil.h.

Constructor & Destructor Documentation

◆ ~NodalUtil()

virtual Nektar::LibUtilities::NodalUtil::~NodalUtil ( )
virtualdefault

◆ NodalUtil()

Nektar::LibUtilities::NodalUtil::NodalUtil ( size_t  degree,
size_t  dim 
)
inlineprotected

Set up the NodalUtil object.

Parameters
dimDimension of the element.
degreePolynomial degree of the element.

Definition at line 95 of file NodalUtil.h.

96 : m_dim(dim), m_degree(degree), m_xi(dim)
97 {
98 }
size_t m_dim
Dimension of the nodal element.
Definition: NodalUtil.h:101
Array< OneD, Array< OneD, NekDouble > > m_xi
Coordinates of the nodal points defining the basis.
Definition: NodalUtil.h:107
size_t m_degree
Degree of the nodal element.
Definition: NodalUtil.h:103

Member Function Documentation

◆ GetDerivMatrix()

SharedMatrix Nektar::LibUtilities::NodalUtil::GetDerivMatrix ( size_t  dir)

Return the derivative matrix for the nodal distribution.

This routine constructs and returns the derivative matrices \(\mathbf{D}_d\) for coordinate directions \( 0 \leq d \leq 2 \), which can be used to evaluate the derivative of a nodal expansion at the points defined by NodalUtil::m_xi. These are calculated as \( \mathbf{D}_d = \mathbf{V}_d \mathbf{V}^{-1} \), where \( \mathbf{V}_d \) is the derivative Vandermonde matrix and \( \mathbf{V} \) is the Vandermonde matrix.

Parameters
dirCoordinate direction in which to evaluate the derivative.
Returns
The derivative matrix for direction dir.

Definition at line 163 of file NodalUtil.cpp.

164{
167 SharedMatrix D = MemoryManager<NekMatrix<NekDouble>>::AllocateSharedPtr(
168 V->GetRows(), V->GetColumns(), 0.0);
169
170 V->Invert();
171
172 *D = (*Vd) * (*V);
173
174 return D;
175}
SharedMatrix GetVandermonde()
Return the Vandermonde matrix for the nodal distribution.
Definition: NodalUtil.cpp:97
SharedMatrix GetVandermondeForDeriv(size_t dir)
Return the Vandermonde matrix of the derivative of the basis functions for the nodal distribution.
Definition: NodalUtil.cpp:130
std::shared_ptr< NekMatrix< NekDouble > > SharedMatrix
Definition: NodalUtil.h:49

References GetVandermonde(), and GetVandermondeForDeriv().

◆ GetInterpolationMatrix()

SharedMatrix Nektar::LibUtilities::NodalUtil::GetInterpolationMatrix ( Array< OneD, Array< OneD, NekDouble > > &  xi)

Construct the interpolation matrix used to evaluate the basis at the points xi inside the element.

This routine returns a matrix \( \mathbf{I}(\mathbf{a}) \) that can be used to evaluate the nodal basis at the points defined by the parameter xi, which is denoted by \( \mathbf{a} = (a_1, \dots, a_N) \) and \( N \) is the number of points in xi.

In particular, if the array \( \mathbf{u} \) with components \( \mathbf{u}_i = u^\delta(\xi_i) \) represents the polynomial approximation of a function \( u \) evaluated at the nodal points NodalUtil::m_xi, then the evaluation of \( u^\delta \) evaluated at the input points \( \mathbf{a} \) is given by \( \mathbf{I}(\mathbf{a})\mathbf{u} \).

Parameters
xiAn array of first size number of spatial dimensions \( d \) and secondary size the number of points to interpolate.
Returns
The interpolation matrix for the points xi.

Definition at line 197 of file NodalUtil.cpp.

199{
200 std::shared_ptr<NodalUtil> subUtil = v_CreateUtil(xi);
202 SharedMatrix matT = subUtil->GetVandermonde();
203 SharedMatrix D = MemoryManager<NekMatrix<NekDouble>>::AllocateSharedPtr(
204 matT->GetRows(), matS->GetColumns(), 0.0);
205
206 matS->Invert();
207
208 *D = (*matT) * (*matS);
209 return D;
210}
virtual std::shared_ptr< NodalUtil > v_CreateUtil(Array< OneD, Array< OneD, NekDouble > > &xi)=0
Construct a NodalUtil object of the appropriate element type for a given set of points.

References GetVandermonde(), and v_CreateUtil().

◆ GetVandermonde()

SharedMatrix Nektar::LibUtilities::NodalUtil::GetVandermonde ( )

Return the Vandermonde matrix for the nodal distribution.

This routine constructs and returns the Vandermonde matrix \(\mathbf{V}\), with each entry as \(\mathbf{V}_{ij} = (\psi_i(\xi_j))\) where \( \psi_i \) is the orthogonal basis obtained through the abstract function NodalUtil::v_OrthoBasis.

Returns
The Vandermonde matrix.

Definition at line 97 of file NodalUtil.cpp.

98{
99 size_t rows = m_numPoints, cols = v_NumModes();
100 SharedMatrix matV =
101 MemoryManager<NekMatrix<NekDouble>>::AllocateSharedPtr(rows, cols, 0.0);
102
103 for (size_t j = 0; j < cols; ++j)
104 {
105 NekVector<NekDouble> col = v_OrthoBasis(j);
106 for (size_t i = 0; i < rows; ++i)
107 {
108 (*matV)(i, j) = col[i];
109 }
110 }
111
112 return matV;
113}
size_t m_numPoints
Total number of nodal points.
Definition: NodalUtil.h:105
virtual NekVector< NekDouble > v_OrthoBasis(const size_t mode)=0
Return the values of the orthogonal basis at the nodal points for a given mode.
virtual size_t v_NumModes()=0
Calculate the number of degrees of freedom for this element.

References m_numPoints, v_NumModes(), and v_OrthoBasis().

Referenced by GetDerivMatrix(), GetInterpolationMatrix(), and GetWeights().

◆ GetVandermondeForDeriv()

SharedMatrix Nektar::LibUtilities::NodalUtil::GetVandermondeForDeriv ( size_t  dir)

Return the Vandermonde matrix of the derivative of the basis functions for the nodal distribution.

This routine constructs and returns the Vandermonde matrix for the derivative of the basis functions \(\mathbf{V}_d\) for coordinate directions \( 0 \leq d \leq 2 \), with each entry as \(\mathbf{V}_{ij} = (\partial_d \psi_i(\xi_j))\) where \( \partial_d\psi_i \) is the derivative of the orthogonal basis obtained through the abstract function NodalUtil::v_OrthoBasisDeriv.

Parameters
dirDirection of derivative in the standard element.
Returns
Vandermonde matrix corresponding with derivative of the basis functions in direction dir.

Definition at line 130 of file NodalUtil.cpp.

131{
132 size_t rows = m_numPoints, cols = v_NumModes();
133 SharedMatrix matV =
134 MemoryManager<NekMatrix<NekDouble>>::AllocateSharedPtr(rows, cols, 0.0);
135
136 for (size_t j = 0; j < cols; ++j)
137 {
138 NekVector<NekDouble> col = v_OrthoBasisDeriv(dir, j);
139 for (size_t i = 0; i < rows; ++i)
140 {
141 (*matV)(i, j) = col[i];
142 }
143 }
144
145 return matV;
146}
virtual NekVector< NekDouble > v_OrthoBasisDeriv(const size_t dir, const size_t mode)=0
Return the values of the derivative of the orthogonal basis at the nodal points for a given mode.

References m_numPoints, v_NumModes(), and v_OrthoBasisDeriv().

Referenced by GetDerivMatrix().

◆ GetWeights()

NekVector< NekDouble > Nektar::LibUtilities::NodalUtil::GetWeights ( )

Obtain the integration weights for the given nodal distribution.

This routine constructs the integration weights for the given nodal distribution inside NodalUtil::m_xi. To do this we solve the linear system \( \mathbf{V}^\top \mathbf{w} = \mathbf{g} \) where \( \mathbf{g}_i = \int_\Omega \psi_i(x)\, dx \), and we use the fact that under the definition of the orthogonal basis for each element type, \( \mathbf{g}_i = 0 \) for \( i > 0 \). We use NodalUtil::v_ModeZeroIntegral to return the analytic value of \( \mathbf{g}_0 \).

Returns
Vector of integration weights for the integration points.

Definition at line 61 of file NodalUtil.cpp.

62{
63 // Get number of modes in orthogonal basis
64 size_t numModes = v_NumModes();
65
66 // If we have the same number of nodes as modes, then we can solve the
67 // linear system V^T w = (1,0,...)
68 if (numModes == m_numPoints)
69 {
70 NekVector<NekDouble> g(m_numPoints, 0.0);
71 g(0) = v_ModeZeroIntegral();
72
74
75 // Solve the system V^T w = g to obtain weights.
76 LinearSystem matL(V);
77 return matL.SolveTranspose(g);
78 }
79 else
80 {
81 // System is either over- or under-determined. Need to do least squares
82 // here using SVD.
83 return NekVector<NekDouble>();
84 }
85}
virtual NekDouble v_ModeZeroIntegral()=0
Return the value of the integral of the zero-th mode for this element.

References GetVandermonde(), m_numPoints, Nektar::LinearSystem::SolveTranspose(), v_ModeZeroIntegral(), and v_NumModes().

◆ v_CreateUtil()

virtual std::shared_ptr< NodalUtil > Nektar::LibUtilities::NodalUtil::v_CreateUtil ( Array< OneD, Array< OneD, NekDouble > > &  xi)
protectedpure virtual

Construct a NodalUtil object of the appropriate element type for a given set of points.

This function is used inside NodalUtil::GetInterpolationMatrix so that the (potentially non-square) Vandermonde matrix can be constructed to create the interpolation matrix at an arbitrary set of points in the domain.

Parameters
xiDistribution of nodal points to create utility with.

Implemented in Nektar::LibUtilities::NodalUtilTriangle, Nektar::LibUtilities::NodalUtilTetrahedron, Nektar::LibUtilities::NodalUtilPrism, Nektar::LibUtilities::NodalUtilQuad, and Nektar::LibUtilities::NodalUtilHex.

Referenced by GetInterpolationMatrix().

◆ v_ModeZeroIntegral()

virtual NekDouble Nektar::LibUtilities::NodalUtil::v_ModeZeroIntegral ( )
protectedpure virtual

Return the value of the integral of the zero-th mode for this element.

Note that for the orthogonal basis under consideration, all modes integrate to zero asides from the zero-th mode. This function is used in NodalUtil::GetWeights to determine integration weights.

Implemented in Nektar::LibUtilities::NodalUtilTriangle, Nektar::LibUtilities::NodalUtilTetrahedron, Nektar::LibUtilities::NodalUtilPrism, Nektar::LibUtilities::NodalUtilQuad, and Nektar::LibUtilities::NodalUtilHex.

Referenced by GetWeights().

◆ v_NumModes()

virtual size_t Nektar::LibUtilities::NodalUtil::v_NumModes ( )
protectedpure virtual

◆ v_OrthoBasis()

virtual NekVector< NekDouble > Nektar::LibUtilities::NodalUtil::v_OrthoBasis ( const size_t  mode)
protectedpure virtual

Return the values of the orthogonal basis at the nodal points for a given mode.

Parameters
modeMode number, which is between 0 and NodalUtil::v_NumModes()
  • 1.
Returns
Orthogonal mode mode evaluated at the nodal points.

Implemented in Nektar::LibUtilities::NodalUtilTriangle, Nektar::LibUtilities::NodalUtilTetrahedron, Nektar::LibUtilities::NodalUtilPrism, Nektar::LibUtilities::NodalUtilQuad, and Nektar::LibUtilities::NodalUtilHex.

Referenced by GetVandermonde().

◆ v_OrthoBasisDeriv()

virtual NekVector< NekDouble > Nektar::LibUtilities::NodalUtil::v_OrthoBasisDeriv ( const size_t  dir,
const size_t  mode 
)
protectedpure virtual

Return the values of the derivative of the orthogonal basis at the nodal points for a given mode.

Parameters
dirCoordinate direction of derivative.
modeMode number, which is between 0 and NodalUtil::v_NumModes()
  • 1.

Implemented in Nektar::LibUtilities::NodalUtilTriangle, Nektar::LibUtilities::NodalUtilTetrahedron, Nektar::LibUtilities::NodalUtilPrism, Nektar::LibUtilities::NodalUtilQuad, and Nektar::LibUtilities::NodalUtilHex.

Referenced by GetVandermondeForDeriv().

Member Data Documentation

◆ m_degree

size_t Nektar::LibUtilities::NodalUtil::m_degree
protected

◆ m_dim

size_t Nektar::LibUtilities::NodalUtil::m_dim
protected

Dimension of the nodal element.

Definition at line 101 of file NodalUtil.h.

◆ m_numPoints

size_t Nektar::LibUtilities::NodalUtil::m_numPoints
protected

◆ m_xi

Array<OneD, Array<OneD, NekDouble> > Nektar::LibUtilities::NodalUtil::m_xi
protected