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