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
46namespace Nektar
47{
48namespace LibUtilities
49{
50
51typedef std::shared_ptr<NekMatrix<NekDouble>> SharedMatrix;
52
53/**
54 * @brief A class to assist in the construction of nodal simplex and hybrid
55 * elements in two and three dimensions.
56 *
57 * The NodalUtil class and its subclasses are designed to take care of some
58 * common issues that arise when considering triangles, tetrahedra and prismatic
59 * elements that are equipped with a nodal Lagrangian basis, defined using a set
60 * of nodal points \f$ \xi_i \f$ that we store in the array
61 * NodalUtil::m_xi. Since one cannot write this basis analytically, we instead
62 * construct the Vandermonde matrix
63 *
64 * \f[ \mathbf{V}_{ij} = \psi_j(\xi_i) \f]
65 *
66 * where \f$ \psi_j \f$ is a basis that spans the polynomial space of the
67 * element. The Vandermonde matrix can then be used to construct the integration
68 * weights, derivative and interpolation matrices. Although this can be any
69 * basis, such as the monomial basis \f$ x^i y^j z^k \f$, in practice this is
70 * numerically unstable at high polynomial orders. Elements are therefore
71 * expected to use the 'traditional' modal orthogonal basis. See Sherwin &
72 * Karniadakis or Hesthaven & Warburton for further details of this basis and
73 * the surrounding numerical issues.
74 *
75 * This class therefore contains the generic logic needed to construct various
76 * matrices, and subclasses override virtual functions that define the
77 * orthogonal basis and its derivatives for a particular element type.
78 */
80{
81public:
82 LIB_UTILITIES_EXPORT virtual ~NodalUtil() = default;
89
90protected:
91 /**
92 * @brief Set up the NodalUtil object.
93 *
94 * @param dim Dimension of the element.
95 * @param degree Polynomial degree of the element.
96 */
97 NodalUtil(size_t degree, size_t dim)
98 : m_dim(dim), m_degree(degree), m_xi(dim)
99 {
100 }
101
102 /// Dimension of the nodal element
103 size_t m_dim;
104 /// Degree of the nodal element
105 size_t m_degree;
106 /// Total number of nodal points
108 /// Coordinates of the nodal points defining the basis
110
111 /**
112 * @brief Return the values of the orthogonal basis at the nodal points for
113 * a given mode.
114 *
115 * @param mode Mode number, which is between 0 and NodalUtil::v_NumModes()
116 * - 1.
117 *
118 * @return Orthogonal mode @p mode evaluated at the nodal points.
119 */
120 virtual NekVector<NekDouble> v_OrthoBasis(const size_t mode) = 0;
121
122 /**
123 * @brief Return the values of the derivative of the orthogonal basis at the
124 * nodal points for a given mode.
125 *
126 * @param dir Coordinate direction of derivative.
127 * @param mode Mode number, which is between 0 and NodalUtil::v_NumModes()
128 * - 1.
129 */
130 virtual NekVector<NekDouble> v_OrthoBasisDeriv(const size_t dir,
131 const size_t mode) = 0;
132
133 /**
134 * @brief Construct a NodalUtil object of the appropriate element type for a
135 * given set of points.
136 *
137 * This function is used inside NodalUtil::GetInterpolationMatrix so that
138 * the (potentially non-square) Vandermonde matrix can be constructed to
139 * create the interpolation matrix at an arbitrary set of points in the
140 * domain.
141 *
142 * @param xi Distribution of nodal points to create utility with.
143 */
144 virtual std::shared_ptr<NodalUtil> v_CreateUtil(
146
147 /**
148 * @brief Return the value of the integral of the zero-th mode for this
149 * element.
150 *
151 * Note that for the orthogonal basis under consideration, all modes
152 * integrate to zero asides from the zero-th mode. This function is used in
153 * NodalUtil::GetWeights to determine integration weights.
154 */
156
157 /**
158 * @brief Calculate the number of degrees of freedom for this element.
159 */
160 virtual size_t v_NumModes() = 0;
161};
162
163/**
164 * @brief Specialisation of the NodalUtil class to support nodal triangular
165 * elements.
166 */
168{
169public:
173
175 {
176 }
177
178protected:
179 /// Mapping from the \f$ (i,j) \f$ indexing of the basis to a continuous
180 /// ordering.
181 std::vector<std::pair<int, int>> m_ordering;
182
183 /// Collapsed coordinates \f$ (\eta_1, \eta_2) \f$ of the nodal points.
185
186 virtual NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
187 virtual NekVector<NekDouble> v_OrthoBasisDeriv(const size_t dir,
188 const size_t mode) override;
189
190 virtual std::shared_ptr<NodalUtil> v_CreateUtil(
191 Array<OneD, Array<OneD, NekDouble>> &xi) override
192 {
194 m_degree, xi[0], xi[1]);
195 }
196
197 virtual NekDouble v_ModeZeroIntegral() override
198 {
199 return 2.0 * sqrt(2.0);
200 }
201
202 virtual size_t v_NumModes() override
203 {
204 return (m_degree + 1) * (m_degree + 2) / 2;
205 }
206};
207
208/**
209 * @brief Specialisation of the NodalUtil class to support nodal tetrahedral
210 * elements.
211 */
213{
214 typedef std::tuple<int, int, int> Mode;
215
216public:
221
223 {
224 }
225
226protected:
227 /// Mapping from the \f$ (i,j,k) \f$ indexing of the basis to a continuous
228 /// ordering.
229 std::vector<Mode> m_ordering;
230
231 /// Collapsed coordinates \f$ (\eta_1, \eta_2, \eta_3) \f$ of the nodal
232 /// points.
234
235 virtual NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
236 virtual NekVector<NekDouble> v_OrthoBasisDeriv(const size_t dir,
237 const size_t mode) override;
238
239 virtual std::shared_ptr<NodalUtil> v_CreateUtil(
240 Array<OneD, Array<OneD, NekDouble>> &xi) override
241 {
243 m_degree, xi[0], xi[1], xi[2]);
244 }
245
246 virtual NekDouble v_ModeZeroIntegral() override
247 {
248 return 8.0 * sqrt(2.0) / 3.0;
249 }
250
251 virtual size_t v_NumModes() override
252 {
253 return (m_degree + 1) * (m_degree + 2) * (m_degree + 3) / 6;
254 }
255};
256
257/**
258 * @brief Specialisation of the NodalUtil class to support nodal prismatic
259 * elements.
260 */
262{
263 typedef std::tuple<int, int, int> Mode;
264
265public:
269
271 {
272 }
273
274protected:
275 /// Mapping from the \f$ (i,j) \f$ indexing of the basis to a continuous
276 /// ordering.
277 std::vector<Mode> m_ordering;
278
279 /// Collapsed coordinates \f$ (\eta_1, \eta_2, \eta_3) \f$ of the nodal
280 /// points.
282
283 virtual NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
284 virtual NekVector<NekDouble> v_OrthoBasisDeriv(const size_t dir,
285 const size_t mode) override;
286
287 virtual std::shared_ptr<NodalUtil> v_CreateUtil(
288 Array<OneD, Array<OneD, NekDouble>> &xi) override
289 {
291 xi[1], xi[2]);
292 }
293
294 virtual NekDouble v_ModeZeroIntegral() override
295 {
296 return 4.0 * sqrt(2.0);
297 }
298
299 virtual size_t v_NumModes() override
300 {
301 return (m_degree + 1) * (m_degree + 1) * (m_degree + 2) / 2;
302 }
303};
304
305/**
306 * @brief Specialisation of the NodalUtil class to support nodal quad elements.
307 */
309{
310public:
313
315 {
316 }
317
318protected:
319 /// Mapping from the \f$ (i,j) \f$ indexing of the basis to a continuous
320 /// ordering.
321 std::vector<std::pair<int, int>> m_ordering;
322
323 virtual NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
324 virtual NekVector<NekDouble> v_OrthoBasisDeriv(const size_t dir,
325 const size_t mode) override;
326
327 virtual std::shared_ptr<NodalUtil> v_CreateUtil(
328 Array<OneD, Array<OneD, NekDouble>> &xi) override
329 {
331 xi[1]);
332 }
333
334 virtual NekDouble v_ModeZeroIntegral() override
335 {
336 return 4.0;
337 }
338
339 virtual size_t v_NumModes() override
340 {
341 return (m_degree + 1) * (m_degree + 1);
342 }
343};
344
345/**
346 * @brief Specialisation of the NodalUtil class to support nodal hex elements.
347 */
349{
350 typedef std::tuple<int, int, int> Mode;
351
352public:
356
358 {
359 }
360
361protected:
362 /// Mapping from the \f$ (i,j,k) \f$ indexing of the basis to a continuous
363 /// ordering.
364 std::vector<Mode> m_ordering;
365
366 virtual NekVector<NekDouble> v_OrthoBasis(const size_t mode) override;
367 virtual NekVector<NekDouble> v_OrthoBasisDeriv(const size_t dir,
368 const size_t mode) override;
369
370 virtual std::shared_ptr<NodalUtil> v_CreateUtil(
371 Array<OneD, Array<OneD, NekDouble>> &xi) override
372 {
374 xi[1], xi[2]);
375 }
376
377 virtual NekDouble v_ModeZeroIntegral() override
378 {
379 return 8.0;
380 }
381
382 virtual size_t v_NumModes() override
383 {
384 return (m_degree + 1) * (m_degree + 1) * (m_degree + 1);
385 }
386};
387
388} // namespace LibUtilities
389} // namespace Nektar
390
391#endif // NODALUTIL_H
#define LIB_UTILITIES_EXPORT
Specialisation of the NodalUtil class to support nodal hex elements.
Definition: NodalUtil.h:349
virtual 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:972
virtual 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:370
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:936
virtual 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:995
virtual size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:382
std::vector< Mode > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:364
std::tuple< int, int, int > Mode
Definition: NodalUtil.h:350
virtual NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:377
A class to assist in the construction of nodal simplex and hybrid elements in two and three dimension...
Definition: NodalUtil.h:80
size_t m_dim
Dimension of the nodal element.
Definition: NodalUtil.h:103
SharedMatrix GetDerivMatrix(size_t dir)
Return the derivative matrix for the nodal distribution.
Definition: NodalUtil.cpp:165
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:109
NekVector< NekDouble > GetWeights()
Obtain the integration weights for the given nodal distribution.
Definition: NodalUtil.cpp:63
SharedMatrix GetVandermonde()
Return the Vandermonde matrix for the nodal distribution.
Definition: NodalUtil.cpp:99
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:105
size_t m_numPoints
Total number of nodal points.
Definition: NodalUtil.h:107
SharedMatrix GetVandermondeForDeriv(size_t dir)
Return the Vandermonde matrix of the derivative of the basis functions for the nodal distribution.
Definition: NodalUtil.cpp:132
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:199
NodalUtil(size_t degree, size_t dim)
Set up the NodalUtil object.
Definition: NodalUtil.h:97
Specialisation of the NodalUtil class to support nodal prismatic elements.
Definition: NodalUtil.h:262
virtual 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:746
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:644
Array< OneD, Array< OneD, NekDouble > > m_eta
Collapsed coordinates of the nodal points.
Definition: NodalUtil.h:281
std::vector< Mode > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:277
virtual 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:706
virtual NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:294
virtual size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:299
virtual 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:287
std::tuple< int, int, int > Mode
Definition: NodalUtil.h:263
Specialisation of the NodalUtil class to support nodal quad elements.
Definition: NodalUtil.h:309
virtual size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:339
virtual NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:334
NodalUtilQuad(size_t degree, Array< OneD, NekDouble > r, Array< OneD, NekDouble > s)
Construct the nodal utility class for a quadrilateral.
Definition: NodalUtil.cpp:825
virtual 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:327
std::vector< std::pair< int, int > > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:321
virtual 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:858
virtual 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:885
Specialisation of the NodalUtil class to support nodal tetrahedral elements.
Definition: NodalUtil.h:213
std::tuple< int, int, int > Mode
Definition: NodalUtil.h:214
virtual 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:487
Array< OneD, Array< OneD, NekDouble > > m_eta
Collapsed coordinates of the nodal points.
Definition: NodalUtil.h:233
virtual size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:251
virtual 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:528
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:412
std::vector< Mode > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:229
virtual 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:239
virtual NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:246
Specialisation of the NodalUtil class to support nodal triangular elements.
Definition: NodalUtil.h:168
virtual 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:328
virtual NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:197
std::vector< std::pair< int, int > > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:181
virtual size_t v_NumModes() override
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:202
NodalUtilTriangle(size_t degree, Array< OneD, NekDouble > r, Array< OneD, NekDouble > s)
Construct the nodal utility class for a triangle.
Definition: NodalUtil.cpp:236
virtual 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:190
Array< OneD, Array< OneD, NekDouble > > m_eta
Collapsed coordinates of the nodal points.
Definition: NodalUtil.h:184
virtual 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:291
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:51
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294