Nektar++
NodalTetEvenlySpaced.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: NodalTetEvenlySpaced.cpp
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: 3D Nodal Tetrahedron Evenly Spaced Point Definitions
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <boost/core/ignore_unused.hpp>
36 
43 #include <vector>
44 
45 namespace Nektar
46 {
47 namespace LibUtilities
48 {
52 
53 namespace
54 {
55 // construct the geometory and set the coordinate of tetrahedron
56 // edges and vertices are ordered as anticlockwise
57 
58 bool isVertex(int x, int y, int z, int npts)
59 {
60  return (x == 0 && y == 0 && z == 0) ||
61  (x == (npts - 1) && y == 0 && z == 0) ||
62  (x == 0 && y == (npts - 1) && z == 0) ||
63  (x == 0 && y == 0 && z == (npts - 1));
64 }
65 
66 bool isEdge_01(int x, int y, int z, int npts)
67 { // edge 0
68  boost::ignore_unused(x, npts);
69  return y == 0 && z == 0;
70 }
71 
72 bool isEdge_12(int x, int y, int z, int npts)
73 { // edge 1
74  return z == 0 && x + y == npts - 1;
75 }
76 
77 bool isEdge_20(int x, int y, int z, int npts)
78 { // edge 2
79  boost::ignore_unused(y, npts);
80  return x == 0 && z == 0;
81 }
82 
83 bool isEdge_03(int x, int y, int z, int npts)
84 { // edge 3
85  boost::ignore_unused(z, npts);
86  return x == 0 && y == 0;
87 }
88 
89 bool isEdge_13(int x, int y, int z, int npts)
90 { // edge 4
91  return y == 0 && x + z == npts - 1;
92 }
93 
94 bool isEdge_23(int x, int y, int z, int npts)
95 { // edge 5
96  return x == 0 && y + z == npts - 1;
97 }
98 
99 bool isEdge(int x, int y, int z, int npts)
100 {
101  return isEdge_01(x, y, z, npts) || isEdge_12(x, y, z, npts) ||
102  isEdge_20(x, y, z, npts) || isEdge_03(x, y, z, npts) ||
103  isEdge_13(x, y, z, npts) || isEdge_23(x, y, z, npts);
104 }
105 
106 bool isFace_012(int x, int y, int z, int npts)
107 { // bottom face (face 0)
108  boost::ignore_unused(x, y, npts);
109  return z == 0;
110 }
111 
112 bool isFace_013(int x, int y, int z, int npts)
113 { // face 1
114  boost::ignore_unused(x, z, npts);
115  return y == 0;
116 }
117 
118 bool isFace_123(int x, int y, int z, int npts)
119 { // face 2
120  return x + y + z == npts - 1;
121 }
122 
123 bool isFace_203(int x, int y, int z, int npts)
124 { // face 3
125  boost::ignore_unused(y, z, npts);
126  return x == 0;
127 }
128 
129 bool isFace(int x, int y, int z, int npts)
130 {
131  return isFace_012(x, y, z, npts) || isFace_013(x, y, z, npts) ||
132  isFace_123(x, y, z, npts) || isFace_203(x, y, z, npts);
133 }
134 } // namespace
135 
136 // Calculate evenly spaced number of points
138 {
139  // Allocate the storage for points
141 
142  // Populate m_points
143  unsigned int npts = GetNumPoints();
144  NekDouble delta = 2.0 / (npts - 1.0);
145  for (unsigned int z = 0, index = 0; z < npts; ++z)
146  {
147  for (unsigned int y = 0; y < npts - z; ++y)
148  {
149  for (unsigned int x = 0; x < npts - z - y; ++x, ++index)
150  {
151  NekDouble xi = -1.0 + x * delta;
152  NekDouble yi = -1.0 + y * delta;
153  NekDouble zi = -1.0 + z * delta;
154 
155  m_points[0][index] = xi;
156  m_points[1][index] = yi;
157  m_points[2][index] = zi;
158  }
159  }
160  }
161 
164  npts - 1, m_points[0], m_points[1], m_points[2]);
165 }
166 
168 {
169  unsigned int npts = GetNumPoints();
170  using std::vector;
171  vector<int> vertex;
172  vector<int> iEdge_01; // interior edge 0
173  vector<int> iEdge_12; // interior edge 1
174  vector<int> iEdge_20; // interior edge 2
175  vector<int> iEdge_03; // interior edge 3
176  vector<int> iEdge_13; // interior edge 4
177  vector<int> iEdge_23; // interior edge 5
178  vector<int> iFace_012; // interior face 0
179  vector<int> iFace_013; // interior face 1
180  vector<int> iFace_123; // interior face 2
181  vector<int> iFace_203; // interior face 3
182  vector<int> interiorVolumePoints; // interior volume points
183  vector<int> map;
184 
185  // Build the lattice tetrahedron left to right - bottom to top
186  for (int z = 0, index = 0; z < npts; ++z)
187  {
188  for (int y = 0; y < npts - z; ++y)
189  {
190  for (int x = 0; x < npts - z - y; ++x, ++index)
191  {
192 
193  if (isVertex(x, y, z, npts))
194  { // vertex
195 
196  vertex.push_back(index);
197  }
198  else if (isEdge(x, y, z, npts))
199  { // interior edge
200 
201  if (isEdge_01(x, y, z, npts))
202  { // interior edge 0
203 
204  iEdge_01.push_back(index);
205  }
206  else if (isEdge_12(x, y, z, npts))
207  { // interior edge 1
208 
209  iEdge_12.push_back(index);
210  }
211  else if (isEdge_20(x, y, z, npts))
212  { // interior edge 2
213 
214  iEdge_20.insert(iEdge_20.begin(), index);
215  }
216  else if (isEdge_03(x, y, z, npts))
217  { // interior edge 3
218 
219  iEdge_03.push_back(index);
220  }
221  else if (isEdge_13(x, y, z, npts))
222  { // interior edge 4
223 
224  iEdge_13.push_back(index);
225  }
226  else if (isEdge_23(x, y, z, npts))
227  { // interior edge 5
228 
229  iEdge_23.push_back(index);
230  }
231  }
232  else if (isFace(x, y, z, npts))
233  { // interior face
234 
235  if (isFace_012(x, y, z, npts))
236  { // interior face 0
237 
238  iFace_012.push_back(index);
239  }
240  else if (isFace_013(x, y, z, npts))
241  { // interior face 1
242 
243  iFace_013.push_back(index);
244  }
245  else if (isFace_123(x, y, z, npts))
246  { // interior face 2
247 
248  iFace_123.push_back(index);
249  }
250  else if (isFace_203(x, y, z, npts))
251  { // interior face 3
252 
253  iFace_203.push_back(index);
254  }
255  }
256  else
257  { // interior volume points
258 
259  interiorVolumePoints.push_back(index);
260  }
261  }
262  }
263  }
264 
265  // Mapping the vertex, edges, faces, interior volume points using the
266  // permutation matrix, so the points are ordered anticlockwise.
267  for (unsigned int n = 0; n < vertex.size(); ++n)
268  {
269 
270  map.push_back(vertex[n]);
271  }
272 
273  for (unsigned int n = 0; n < iEdge_01.size(); ++n)
274  {
275 
276  map.push_back(iEdge_01[n]);
277  }
278 
279  for (unsigned int n = 0; n < iEdge_12.size(); ++n)
280  {
281 
282  map.push_back(iEdge_12[n]);
283  }
284 
285  for (unsigned int n = 0; n < iEdge_20.size(); ++n)
286  {
287 
288  map.push_back(iEdge_20[n]);
289  }
290 
291  for (unsigned int n = 0; n < iEdge_03.size(); ++n)
292  {
293 
294  map.push_back(iEdge_03[n]);
295  }
296 
297  for (unsigned int n = 0; n < iEdge_13.size(); ++n)
298  {
299 
300  map.push_back(iEdge_13[n]);
301  }
302 
303  for (unsigned int n = 0; n < iEdge_23.size(); ++n)
304  {
305 
306  map.push_back(iEdge_23[n]);
307  }
308 
309  for (unsigned int n = 0; n < iFace_012.size(); ++n)
310  {
311 
312  map.push_back(iFace_012[n]);
313  }
314 
315  for (unsigned int n = 0; n < iFace_013.size(); ++n)
316  {
317 
318  map.push_back(iFace_013[n]);
319  }
320 
321  for (unsigned int n = 0; n < iFace_123.size(); ++n)
322  {
323 
324  map.push_back(iFace_123[n]);
325  }
326 
327  for (unsigned int n = 0; n < iFace_203.size(); ++n)
328  {
329 
330  map.push_back(iFace_203[n]);
331  }
332 
333  for (unsigned int n = 0; n < interiorVolumePoints.size(); ++n)
334  {
335 
336  map.push_back(interiorVolumePoints[n]);
337  }
338 
339  Array<OneD, NekDouble> points[3];
343  for (unsigned int index = 0; index < map.size(); ++index)
344  {
345 
346  points[0][index] = m_points[0][index];
347  points[1][index] = m_points[1][index];
348  points[2][index] = m_points[2][index];
349  }
350 
351  for (unsigned int index = 0; index < map.size(); ++index)
352  {
353 
354  m_points[0][index] = points[0][map[index]];
355  m_points[1][index] = points[1][map[index]];
356  m_points[2][index] = points[2][map[index]];
357  }
358 }
359 
361 {
362  // Allocate storage for points
364 
365  typedef DataType T;
366 
367  // Solve the Vandermonde system of integrals for the weight vector
368  NekVector<T> w = m_util->GetWeights();
370 }
371 
372 // ////////////////////////////////////////
373 // CalculateInterpMatrix()
375  const Array<OneD, const NekDouble> &xia,
376  const Array<OneD, const NekDouble> &yia,
378 {
380  xi[0] = xia;
381  xi[1] = yia;
382  xi[2] = zia;
383 
384  std::shared_ptr<NekMatrix<NekDouble>> mat =
385  m_util->GetInterpolationMatrix(xi);
386  Vmath::Vcopy(mat->GetRows() * mat->GetColumns(), mat->GetRawPtr(), 1,
387  &interp[0], 1);
388 }
389 
390 // ////////////////////////////////////////
391 // CalculateDerivMatrix()
393 {
394  // Allocate the derivative matrix.
396 
397  m_derivmatrix[0] = m_util->GetDerivMatrix(0);
398  m_derivmatrix[1] = m_util->GetDerivMatrix(1);
399  m_derivmatrix[2] = m_util->GetDerivMatrix(2);
400 }
401 
402 std::shared_ptr<PointsBaseType> NodalTetEvenlySpaced::Create(
403  const PointsKey &key)
404 {
405  std::shared_ptr<PointsBaseType> returnval(
407 
408  returnval->Initialize();
409 
410  return returnval;
411 }
412 
413 } // namespace LibUtilities
414 } // namespace Nektar
bool RegisterCreator(const KeyType &key, const CreateFuncType &createFunc)
Register the given function and associate it with the key. The return value is just to facilitate cal...
Definition: NekManager.hpp:170
std::shared_ptr< NodalUtilTetrahedron > m_util
void CalculateInterpMatrix(const Array< OneD, const NekDouble > &xi, const Array< OneD, const NekDouble > &yi, const Array< OneD, const NekDouble > &zi, Array< OneD, NekDouble > &interp)
static std::shared_ptr< PointsBaseType > Create(const PointsKey &key)
Array< OneD, DataType > m_points[3]
Storage for the point locations, allowing for up to a 3D points storage.
Definition: Points.h:375
MatrixSharedPtrType m_derivmatrix[3]
Derivative matrices.
Definition: Points.h:381
unsigned int GetNumPoints() const
Definition: Points.h:273
unsigned int GetTotNumPoints() const
Definition: Points.h:278
Array< OneD, DataType > m_weights
Quadrature weights for the weights.
Definition: Points.h:377
Defines a specification for a set of points.
Definition: Points.h:59
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Array< OneD, DataType > & GetPtr()
Definition: NekVector.cpp:217
unsigned int GetRows() const
Definition: NekVector.cpp:206
PointsManagerT & PointsManager(void)
@ eNodalTetEvenlySpaced
3D Evenly-spaced points on a Tetrahedron
Definition: PointsType.h:86
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
double NekDouble
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1255