Nektar++
NodalUtil.h
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: NodalUtil.h
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: 2D and 3D Nodal Utilities header file Basis function,
32// Interpolation, Integral, Derivation, etc.
33//
34///////////////////////////////////////////////////////////////////////////////
35
36#ifndef NODALUTIL_H
37#define NODALUTIL_H
38
39#include <tuple>
40
45
47{
48
49typedef std::shared_ptr<NekMatrix<NekDouble>> SharedMatrix;
50
51/**
52 * @brief A class to assist in the construction of nodal simplex and hybrid
53 * elements in two and three dimensions.
54 *
55 * The NodalUtil class and its subclasses are designed to take care of some
56 * common issues that arise when considering triangles, tetrahedra and prismatic
57 * elements that are equipped with a nodal Lagrangian basis, defined using a set
58 * of nodal points \f$ \xi_i \f$ that we store in the array
59 * NodalUtil::m_xi. Since one cannot write this basis analytically, we instead
60 * construct the Vandermonde matrix
61 *
62 * \f[ \mathbf{V}_{ij} = \psi_j(\xi_i) \f]
63 *
64 * where \f$ \psi_j \f$ is a basis that spans the polynomial space of the
65 * element. The Vandermonde matrix can then be used to construct the integration
66 * weights, derivative and interpolation matrices. Although this can be any
67 * basis, such as the monomial basis \f$ x^i y^j z^k \f$, in practice this is
68 * numerically unstable at high polynomial orders. Elements are therefore
69 * expected to use the 'traditional' modal orthogonal basis. See Sherwin &
70 * Karniadakis or Hesthaven & Warburton for further details of this basis and
71 * the surrounding numerical issues.
72 *
73 * This class therefore contains the generic logic needed to construct various
74 * matrices, and subclasses override virtual functions that define the
75 * orthogonal basis and its derivatives for a particular element type.
76 */
78{
79public:
80 LIB_UTILITIES_EXPORT virtual ~NodalUtil() = default;
87
88protected:
89 /**
90 * @brief Set up the NodalUtil object.
91 *
92 * @param dim Dimension of the element.
93 * @param degree Polynomial degree of the element.
94 */
95 NodalUtil(size_t degree, size_t dim)
96 : m_dim(dim), m_degree(degree), m_xi(dim)
97 {
98 }
99
100 /// Dimension of the nodal element
101 size_t m_dim;
102 /// Degree of the nodal element
103 size_t m_degree;
104 /// Total number of nodal points
106 /// Coordinates of the nodal points defining the basis
108
109 /**
110 * @brief Return the values of the orthogonal basis at the nodal points for
111 * a given mode.
112 *
113 * @param mode Mode number, which is between 0 and NodalUtil::v_NumModes()
114 * - 1.
115 *
116 * @return Orthogonal mode @p mode evaluated at the nodal points.
117 */
118 virtual NekVector<NekDouble> v_OrthoBasis(const size_t mode) = 0;
119
120 /**
121 * @brief Return the values of the derivative of the orthogonal basis at the
122 * nodal points for a given mode.
123 *
124 * @param dir Coordinate direction of derivative.
125 * @param mode Mode number, which is between 0 and NodalUtil::v_NumModes()
126 * - 1.
127 */
128 virtual NekVector<NekDouble> v_OrthoBasisDeriv(const size_t dir,
129 const size_t mode) = 0;
130
131 /**
132 * @brief Construct a NodalUtil object of the appropriate element type for a
133 * given set of points.
134 *
135 * This function is used inside NodalUtil::GetInterpolationMatrix so that
136 * the (potentially non-square) Vandermonde matrix can be constructed to
137 * create the interpolation matrix at an arbitrary set of points in the
138 * domain.
139 *
140 * @param xi Distribution of nodal points to create utility with.
141 */
142 virtual std::shared_ptr<NodalUtil> v_CreateUtil(
144
145 /**
146 * @brief Return the value of the integral of the zero-th mode for this
147 * element.
148 *
149 * Note that for the orthogonal basis under consideration, all modes
150 * integrate to zero asides from the zero-th mode. This function is used in
151 * NodalUtil::GetWeights to determine integration weights.
152 */
154
155 /**
156 * @brief Calculate the number of degrees of freedom for this element.
157 */
158 virtual size_t v_NumModes() = 0;
159};
160
161/**
162 * @brief Specialisation of the NodalUtil class to support nodal triangular
163 * elements.
164 */
166{
167public:
171
173 {
174 }
175
176protected:
177 /// Mapping from the \f$ (i,j) \f$ indexing of the basis to a continuous
178 /// ordering.
179 std::vector<std::pair<int, int>> m_ordering;
180
181 /// Collapsed coordinates \f$ (\eta_1, \eta_2) \f$ of the nodal points.
183
184 NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
186 const size_t mode) override;
187
188 std::shared_ptr<NodalUtil> v_CreateUtil(
189 Array<OneD, Array<OneD, NekDouble>> &xi) override
190 {
192 m_degree, xi[0], xi[1]);
193 }
194
196 {
197 return 2.0 * sqrt(2.0);
198 }
199
200 size_t v_NumModes() override
201 {
202 return (m_degree + 1) * (m_degree + 2) / 2;
203 }
204};
205
206/**
207 * @brief Specialisation of the NodalUtil class to support nodal tetrahedral
208 * elements.
209 */
211{
212 typedef std::tuple<int, int, int> Mode;
213
214public:
219
221 {
222 }
223
224protected:
225 /// Mapping from the \f$ (i,j,k) \f$ indexing of the basis to a continuous
226 /// ordering.
227 std::vector<Mode> m_ordering;
228
229 /// Collapsed coordinates \f$ (\eta_1, \eta_2, \eta_3) \f$ of the nodal
230 /// points.
232
233 NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
235 const size_t mode) override;
236
237 std::shared_ptr<NodalUtil> v_CreateUtil(
238 Array<OneD, Array<OneD, NekDouble>> &xi) override
239 {
241 m_degree, xi[0], xi[1], xi[2]);
242 }
243
245 {
246 return 8.0 * sqrt(2.0) / 3.0;
247 }
248
249 size_t v_NumModes() override
250 {
251 return (m_degree + 1) * (m_degree + 2) * (m_degree + 3) / 6;
252 }
253};
254
255/**
256 * @brief Specialisation of the NodalUtil class to support nodal prismatic
257 * elements.
258 */
260{
261 typedef std::tuple<int, int, int> Mode;
262
263public:
267
269 {
270 }
271
272protected:
273 /// Mapping from the \f$ (i,j) \f$ indexing of the basis to a continuous
274 /// ordering.
275 std::vector<Mode> m_ordering;
276
277 /// Collapsed coordinates \f$ (\eta_1, \eta_2, \eta_3) \f$ of the nodal
278 /// points.
280
281 NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
283 const size_t mode) override;
284
285 std::shared_ptr<NodalUtil> v_CreateUtil(
286 Array<OneD, Array<OneD, NekDouble>> &xi) override
287 {
289 xi[1], xi[2]);
290 }
291
293 {
294 return 4.0 * sqrt(2.0);
295 }
296
297 size_t v_NumModes() override
298 {
299 return (m_degree + 1) * (m_degree + 1) * (m_degree + 2) / 2;
300 }
301};
302
303/**
304 * @brief Specialisation of the NodalUtil class to support nodal quad elements.
305 */
307{
308public:
311
313 {
314 }
315
316protected:
317 /// Mapping from the \f$ (i,j) \f$ indexing of the basis to a continuous
318 /// ordering.
319 std::vector<std::pair<int, int>> m_ordering;
320
321 NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
323 const size_t mode) override;
324
325 std::shared_ptr<NodalUtil> v_CreateUtil(
326 Array<OneD, Array<OneD, NekDouble>> &xi) override
327 {
329 xi[1]);
330 }
331
333 {
334 return 4.0;
335 }
336
337 size_t v_NumModes() override
338 {
339 return (m_degree + 1) * (m_degree + 1);
340 }
341};
342
343/**
344 * @brief Specialisation of the NodalUtil class to support nodal hex elements.
345 */
347{
348 typedef std::tuple<int, int, int> Mode;
349
350public:
354
356 {
357 }
358
359protected:
360 /// Mapping from the \f$ (i,j,k) \f$ indexing of the basis to a continuous
361 /// ordering.
362 std::vector<Mode> m_ordering;
363
364 NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
366 const size_t mode) override;
367
368 std::shared_ptr<NodalUtil> v_CreateUtil(
369 Array<OneD, Array<OneD, NekDouble>> &xi) override
370 {
372 xi[1], xi[2]);
373 }
374
376 {
377 return 8.0;
378 }
379
380 size_t v_NumModes() override
381 {
382 return (m_degree + 1) * (m_degree + 1) * (m_degree + 1);
383 }
384};
385
386} // namespace Nektar::LibUtilities
387
388#endif // NODALUTIL_H
#define LIB_UTILITIES_EXPORT
Specialisation of the NodalUtil class to support nodal hex elements.
Definition: NodalUtil.h:347
size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:380
NekVector< NekDouble > v_OrthoBasis(const size_t mode) override
Return the value of the modal functions for the hex element at the nodal points m_xi for a given mode...
Definition: NodalUtil.cpp:970
NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:375
NodalUtilHex(size_t degree, Array< OneD, NekDouble > r, Array< OneD, NekDouble > s, Array< OneD, NekDouble > t)
Construct the nodal utility class for a hexahedron.
Definition: NodalUtil.cpp:934
NekVector< NekDouble > v_OrthoBasisDeriv(const size_t dir, const size_t mode) override
Return the values of the derivative of the orthogonal basis at the nodal points for a given mode.
Definition: NodalUtil.cpp:996
std::vector< Mode > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:362
std::shared_ptr< NodalUtil > v_CreateUtil(Array< OneD, Array< OneD, NekDouble > > &xi) override
Construct a NodalUtil object of the appropriate element type for a given set of points.
Definition: NodalUtil.h:368
std::tuple< int, int, int > Mode
Definition: NodalUtil.h:348
A class to assist in the construction of nodal simplex and hybrid elements in two and three dimension...
Definition: NodalUtil.h:78
size_t m_dim
Dimension of the nodal element.
Definition: NodalUtil.h:101
SharedMatrix GetDerivMatrix(size_t dir)
Return the derivative matrix for the nodal distribution.
Definition: NodalUtil.cpp:163
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.
Array< OneD, Array< OneD, NekDouble > > m_xi
Coordinates of the nodal points defining the basis.
Definition: NodalUtil.h:107
NekVector< NekDouble > GetWeights()
Obtain the integration weights for the given nodal distribution.
Definition: NodalUtil.cpp:61
SharedMatrix GetVandermonde()
Return the Vandermonde matrix for the nodal distribution.
Definition: NodalUtil.cpp:97
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.
size_t m_degree
Degree of the nodal element.
Definition: NodalUtil.h:103
size_t m_numPoints
Total number of nodal points.
Definition: NodalUtil.h:105
SharedMatrix GetVandermondeForDeriv(size_t dir)
Return the Vandermonde matrix of the derivative of the basis functions for the nodal distribution.
Definition: NodalUtil.cpp:130
virtual NekDouble v_ModeZeroIntegral()=0
Return the value of the integral of the zero-th mode for this element.
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.
SharedMatrix GetInterpolationMatrix(Array< OneD, Array< OneD, NekDouble > > &xi)
Construct the interpolation matrix used to evaluate the basis at the points xi inside the element.
Definition: NodalUtil.cpp:197
NodalUtil(size_t degree, size_t dim)
Set up the NodalUtil object.
Definition: NodalUtil.h:95
Specialisation of the NodalUtil class to support nodal prismatic elements.
Definition: NodalUtil.h:260
std::shared_ptr< NodalUtil > v_CreateUtil(Array< OneD, Array< OneD, NekDouble > > &xi) override
Construct a NodalUtil object of the appropriate element type for a given set of points.
Definition: NodalUtil.h:285
NekVector< NekDouble > v_OrthoBasisDeriv(const size_t dir, const size_t mode) override
Return the value of the derivative of the modal functions for the prismatic element at the nodal poin...
Definition: NodalUtil.cpp:744
NodalUtilPrism(size_t degree, Array< OneD, NekDouble > r, Array< OneD, NekDouble > s, Array< OneD, NekDouble > t)
Construct the nodal utility class for a prism.
Definition: NodalUtil.cpp:642
Array< OneD, Array< OneD, NekDouble > > m_eta
Collapsed coordinates of the nodal points.
Definition: NodalUtil.h:279
std::vector< Mode > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:275
NekVector< NekDouble > v_OrthoBasis(const size_t mode) override
Return the value of the modal functions for the prismatic element at the nodal points m_xi for a give...
Definition: NodalUtil.cpp:704
size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:297
std::tuple< int, int, int > Mode
Definition: NodalUtil.h:261
NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:292
Specialisation of the NodalUtil class to support nodal quad elements.
Definition: NodalUtil.h:307
std::shared_ptr< NodalUtil > v_CreateUtil(Array< OneD, Array< OneD, NekDouble > > &xi) override
Construct a NodalUtil object of the appropriate element type for a given set of points.
Definition: NodalUtil.h:325
NodalUtilQuad(size_t degree, Array< OneD, NekDouble > r, Array< OneD, NekDouble > s)
Construct the nodal utility class for a quadrilateral.
Definition: NodalUtil.cpp:823
NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:332
std::vector< std::pair< int, int > > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:319
size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:337
NekVector< NekDouble > v_OrthoBasis(const size_t mode) override
Return the value of the modal functions for the quad element at the nodal points m_xi for a given mod...
Definition: NodalUtil.cpp:856
NekVector< NekDouble > v_OrthoBasisDeriv(const size_t dir, const size_t mode) override
Return the value of the derivative of the modal functions for the quadrilateral element at the nodal ...
Definition: NodalUtil.cpp:883
Specialisation of the NodalUtil class to support nodal tetrahedral elements.
Definition: NodalUtil.h:211
NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:244
std::tuple< int, int, int > Mode
Definition: NodalUtil.h:212
NekVector< NekDouble > v_OrthoBasis(const size_t mode) override
Return the value of the modal functions for the tetrahedral element at the nodal points m_xi for a gi...
Definition: NodalUtil.cpp:485
Array< OneD, Array< OneD, NekDouble > > m_eta
Collapsed coordinates of the nodal points.
Definition: NodalUtil.h:231
std::shared_ptr< NodalUtil > v_CreateUtil(Array< OneD, Array< OneD, NekDouble > > &xi) override
Construct a NodalUtil object of the appropriate element type for a given set of points.
Definition: NodalUtil.h:237
size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:249
NekVector< NekDouble > v_OrthoBasisDeriv(const size_t dir, const size_t mode) override
Return the value of the derivative of the modal functions for the tetrahedral element at the nodal po...
Definition: NodalUtil.cpp:526
NodalUtilTetrahedron(size_t degree, Array< OneD, NekDouble > r, Array< OneD, NekDouble > s, Array< OneD, NekDouble > t)
Construct the nodal utility class for a tetrahedron.
Definition: NodalUtil.cpp:410
std::vector< Mode > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:227
Specialisation of the NodalUtil class to support nodal triangular elements.
Definition: NodalUtil.h:166
NekVector< NekDouble > v_OrthoBasisDeriv(const size_t dir, const size_t mode) override
Return the value of the derivative of the modal functions for the triangular element at the nodal poi...
Definition: NodalUtil.cpp:326
std::vector< std::pair< int, int > > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:179
NodalUtilTriangle(size_t degree, Array< OneD, NekDouble > r, Array< OneD, NekDouble > s)
Construct the nodal utility class for a triangle.
Definition: NodalUtil.cpp:234
NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:195
size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:200
std::shared_ptr< NodalUtil > v_CreateUtil(Array< OneD, Array< OneD, NekDouble > > &xi) override
Construct a NodalUtil object of the appropriate element type for a given set of points.
Definition: NodalUtil.h:188
Array< OneD, Array< OneD, NekDouble > > m_eta
Collapsed coordinates of the nodal points.
Definition: NodalUtil.h:182
NekVector< NekDouble > v_OrthoBasis(const size_t mode) override
Return the value of the modal functions for the triangular element at the nodal points m_xi for a giv...
Definition: NodalUtil.cpp:289
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
std::shared_ptr< NekMatrix< NekDouble > > SharedMatrix
Definition: NodalUtil.h:49
double NekDouble
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294