Nektar++
Loading...
Searching...
No Matches
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
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
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...
NekDouble v_ModeZeroIntegral() override
Return the value of the integral of the zero-th mode for this element.
Definition NodalUtil.h:375
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.
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.
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.
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.
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...
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...
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
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...
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 ...
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...
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...
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...
std::vector< std::pair< int, int > > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition NodalUtil.h:179
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...
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
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290