Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: 2D and 3D Nodal Triangle and Tetrahedron Utilities header file
33 // Basis function, Interpolation, Integral, Derivation, etc.
34 //
35 ///////////////////////////////////////////////////////////////////////////////
36 
37 #ifndef NODALUTIL_H
38 #define NODALUTIL_H
39 
40 #include <boost/tuple/tuple.hpp>
41 
47 
49 
50 
51 namespace Nektar
52 {
53 namespace LibUtilities
54 {
55 
56 typedef boost::shared_ptr<NekMatrix<NekDouble> > SharedMatrix;
57 
58 /**
59  * @brief A class to assist in the construction of nodal simplex and hybrid
60  * elements in two and three dimensions.
61  *
62  * The NodalUtil class and its subclasses are designed to take care of some
63  * common issues that arise when considering triangles, tetrahedra and prismatic
64  * elements that are equipped with a nodal Lagrangian basis, defined using a set
65  * of nodal points \f$ \xi_i \f$ that we store in the array
66  * NodalUtil::m_xi. Since one cannot write this basis analytically, we instead
67  * construct the Vandermonde matrix
68  *
69  * \f[ \mathbf{V}_{ij} = \psi_j(\xi_i) \f]
70  *
71  * where \f$ \psi_j \f$ is a basis that spans the polynomial space of the
72  * element. The Vandermonde matrix can then be used to construct the integration
73  * weights, derivative and interpolation matrices. Although this can be any
74  * basis, such as the monomial basis \f$ x^i y^j z^k \f$, in practice this is
75  * numerically unstable at high polynomial orders. Elements are therefore
76  * expected to use the 'traditional' modal orthogonal basis. See Sherwin &
77  * Karniadakis or Hesthaven & Warburton for further details of this basis and
78  * the surrounding numerical issues.
79  *
80  * This class therefore contains the generic logic needed to construct various
81  * matrices, and subclasses override virtual functions that define the
82  * orthogonal basis and its derivatives for a particular element type.
83  */
84 class NodalUtil
85 {
86 public:
88  LIB_UTILITIES_EXPORT SharedMatrix GetVandermonde();
89  LIB_UTILITIES_EXPORT SharedMatrix GetVandermondeForDeriv(int dir);
90  LIB_UTILITIES_EXPORT SharedMatrix GetDerivMatrix(int dir);
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 boost::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  */
158  virtual NekDouble v_ModeZeroIntegral() = 0;
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 boost::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 boost::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 boost::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 boost::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 boost::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 boost::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 boost::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 boost::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
std::vector< Mode > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:232
virtual NekDouble v_ModeZeroIntegral()
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:298
virtual boost::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_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:537
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
virtual int v_NumModes()
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:205
A class to assist in the construction of nodal simplex and hybrid elements in two and three dimension...
Definition: NodalUtil.h:84
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:877
Specialisation of the NodalUtil class to support nodal triangular elements.
Definition: NodalUtil.h:170
boost::tuple< int, int, int > Mode
Definition: NodalUtil.h:355
virtual NekDouble v_ModeZeroIntegral()
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:339
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:655
Array< OneD, Array< OneD, NekDouble > > m_eta
Collapsed coordinates of the nodal points.
Definition: NodalUtil.h:285
virtual boost::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
Array< OneD, Array< OneD, NekDouble > > m_eta
Collapsed coordinates of the nodal points.
Definition: NodalUtil.h:236
SharedMatrix GetVandermondeForDeriv(int dir)
Return the Vandermonde matrix of the derivative of the basis functions for the nodal distribution...
Definition: NodalUtil.cpp:135
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:202
boost::tuple< int, int, int > Mode
Definition: NodalUtil.h:217
virtual NekDouble v_ModeZeroIntegral()
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:383
std::vector< std::pair< int, int > > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:184
int m_degree
Degree of the nodal element.
Definition: NodalUtil.h:108
boost::shared_ptr< NekMatrix< NekDouble > > SharedMatrix
Definition: NodalUtil.h:56
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:295
#define LIB_UTILITIES_EXPORT
Specialisation of the NodalUtil class to support nodal hex elements.
Definition: NodalUtil.h:353
virtual NekDouble v_ModeZeroIntegral()
Return the value of the integral of the zero-th mode for this element.
Definition: NodalUtil.h:200
Array< OneD, Array< OneD, NekDouble > > m_eta
Collapsed coordinates of the nodal points.
Definition: NodalUtil.h:187
SharedMatrix GetDerivMatrix(int dir)
Return the derivative matrix for the nodal distribution.
Definition: NodalUtil.cpp:168
std::vector< Mode > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:370
virtual int v_NumModes()
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:303
NodalUtil(int degree, int dim)
Set up the NodalUtil object.
Definition: NodalUtil.h:101
double NekDouble
NekVector< NekDouble > GetWeights()
Obtain the integration weights for the given nodal distribution.
Definition: NodalUtil.cpp:66
virtual boost::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
virtual int v_NumModes()
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:388
Specialisation of the NodalUtil class to support nodal prismatic elements.
Definition: NodalUtil.h:264
virtual int v_NumModes()
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:344
virtual boost::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 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:904
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:718
SharedMatrix GetVandermonde()
Return the Vandermonde matrix for the nodal distribution.
Definition: NodalUtil.cpp:102
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:956
NodalUtilQuad(int degree, Array< OneD, NekDouble > r, Array< OneD, NekDouble > s)
Construct the nodal utility class for a quadrilateral.
Definition: NodalUtil.cpp:843
virtual boost::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_xi
Coordinates of the nodal points defining the basis.
Definition: NodalUtil.h:112
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:1020
std::vector< Mode > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:281
virtual NekVector< NekDouble > v_OrthoBasis(const int mode)=0
Return the values of the orthogonal basis at the nodal points for a given mode.
virtual int v_NumModes()
Calculate the number of degrees of freedom for this element.
Definition: NodalUtil.h:254
Specialisation of the NodalUtil class to support nodal quad elements.
Definition: NodalUtil.h:312
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:760
int m_numPoints
Total number of nodal points.
Definition: NodalUtil.h:110
NodalUtilTriangle(int degree, Array< OneD, NekDouble > r, Array< OneD, NekDouble > s)
Construct the nodal utility class for a triangle.
Definition: NodalUtil.cpp:239
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:994
boost::tuple< int, int, int > Mode
Definition: NodalUtil.h:266
std::vector< std::pair< int, int > > m_ordering
Mapping from the indexing of the basis to a continuous ordering.
Definition: NodalUtil.h:326
virtual int v_NumModes()=0
Calculate the number of degrees of freedom for this element.
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:333
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...
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_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:495
virtual NekDouble v_ModeZeroIntegral()=0
Return the value of the integral of the zero-th mode for this element.
int m_dim
Dimension of the nodal element.
Definition: NodalUtil.h:106
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:420
Specialisation of the NodalUtil class to support nodal tetrahedral elements.
Definition: NodalUtil.h:215
virtual boost::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