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