Nektar++
NodalPrismEvenlySpaced.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File NodalPrismEvenlySpaced.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 Prism Evenly Spaced Point Definitions
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <boost/core/ignore_unused.hpp>
36 
41 #include <vector>
42 
43 namespace Nektar
44 {
45  namespace LibUtilities
46  {
49  };
50 
51  namespace
52  {
53  bool isVertex(int x, int y, int z, int npts)
54  {
55  return (x == 0 && y == 0 && z == 0 ) ||
56  (x == (npts-1) && y == 0 && z == 0 ) ||
57  (x == (npts-1) && y == (npts-1) && z == 0 ) ||
58  (x == 0 && y == (npts-1) && z == 0 ) ||
59  (x == 0 && y == 0 && z == (npts-1)) ||
60  (x == 0 && y == (npts-1) && z == (npts-1));
61  }
62 
63  bool isEdge_01(int x, int y, int z, int npts)
64  {
65  boost::ignore_unused(x, npts);
66  return y == 0 && z == 0;
67  }
68 
69  bool isEdge_12(int x, int y, int z, int npts)
70  {
71  boost::ignore_unused(y);
72  return x == (npts-1) && z == 0;
73  }
74 
75  bool isEdge_23(int x, int y, int z, int npts)
76  {
77  boost::ignore_unused(x);
78  return y == (npts-1) && z == 0;
79  }
80 
81  bool isEdge_30(int x, int y, int z, int npts)
82  {
83  boost::ignore_unused(y, npts);
84  return x == 0 && z == 0;
85  }
86 
87  bool isEdge_04(int x, int y, int z, int npts)
88  {
89  boost::ignore_unused(z, npts);
90  return x == 0 && y == 0;
91  }
92 
93  bool isEdge_14(int x, int y, int z, int npts)
94  {
95  return x + z == (npts-1) && y == 0;
96  }
97 
98  bool isEdge_25(int x, int y, int z, int npts)
99  {
100  return x + z == (npts-1) && y == (npts-1);
101  }
102 
103  bool isEdge_35(int x, int y, int z, int npts)
104  {
105  boost::ignore_unused(z);
106  return x == 0 && y == (npts-1);
107  }
108 
109  bool isEdge_45(int x, int y, int z, int npts)
110  {
111  boost::ignore_unused(y);
112  return x == 0 && z == (npts-1);
113  }
114 
115  bool isEdge(int x, int y, int z, int npts){
116  return isEdge_01(x,y,z,npts) || isEdge_12(x,y,z,npts) ||
117  isEdge_23(x,y,z,npts) || isEdge_30(x,y,z,npts) ||
118  isEdge_04(x,y,z,npts) || isEdge_14(x,y,z,npts) ||
119  isEdge_25(x,y,z,npts) || isEdge_35(x,y,z,npts) ||
120  isEdge_45(x,y,z,npts);
121  }
122 
123  bool isFace_0123(int x, int y, int z, int npts)
124  {
125  boost::ignore_unused(x, y, npts);
126  return z == 0;
127  }
128 
129  bool isFace_014(int x, int y, int z, int npts)
130  {
131  boost::ignore_unused(x, z, npts);
132  return y == 0;
133  }
134 
135  bool isFace_1254(int x, int y, int z, int npts)
136  {
137  boost::ignore_unused(y);
138  return x + z == npts-1;
139  }
140 
141  bool isFace_325(int x, int y, int z, int npts)
142  {
143  boost::ignore_unused(x, z);
144  return y == (npts-1);
145  }
146 
147  bool isFace_0354(int x, int y, int z, int npts)
148  {
149  boost::ignore_unused(y, z, npts);
150  return x == 0;
151  }
152 
153  bool isFace(int x, int y, int z, int npts){
154  return isFace_0123(x,y,z,npts) || isFace_014(x,y,z,npts) ||
155  isFace_1254(x,y,z,npts) || isFace_325(x,y,z,npts) ||
156  isFace_0354(x,y,z,npts);
157  }
158  }
159 
160  // Calculate evenly spaced number of points
162  {
163  // Allocate the storage for points
165 
166  // Populate m_points
167  unsigned int npts = GetNumPoints();
168  NekDouble delta = 2.0/(npts - 1.0);
169  for(unsigned int z=0, index=0; z<npts; ++z){
170  for(unsigned int y=0; y<npts; ++y){
171  for(unsigned int x=0; x<npts-z; ++x, ++index){
172  NekDouble xi = -1.0 + x*delta;
173  NekDouble yi = -1.0 + y*delta;
174  NekDouble zi = -1.0 + z*delta;
175 
176  m_points[0][index] = xi;
177  m_points[1][index] = yi;
178  m_points[2][index] = zi;
179  }
180  }
181  }
182 
185  npts - 1, m_points[0], m_points[1], m_points[2]);
186  }
187 
189  {
190  unsigned int npts = GetNumPoints();
191  using std::vector;
192  vector<int> vertex;
193  vector<int> iEdge_01; // interior edge 0
194  vector<int> iEdge_12; // interior edge 1
195  vector<int> iEdge_23; // interior edge 2
196  vector<int> iEdge_30; // interior edge 3
197  vector<int> iEdge_04; // interior edge 4
198  vector<int> iEdge_14; // interior edge 5
199  vector<int> iEdge_25; // interior edge 6
200  vector<int> iEdge_35; // interior edge 7
201  vector<int> iEdge_45; // interior edge 8
202  vector<int> iFace_0123; // interior face 0
203  vector<int> iFace_014; // interior face 1
204  vector<int> iFace_1254; // interior face 2
205  vector<int> iFace_325; // interior face 3
206  vector<int> iFace_0354; // interior face 4
207  vector<int> interiorVolumePoints; // interior volume points
208  vector<int> map;
209 
210  // Build the lattice prism left to right - bottom to top
211  for(unsigned int z=0, index=0; z<npts; ++z){
212  for(unsigned int y=0; y<npts; ++y){
213  for(unsigned int x=0; x<npts-z; ++x, ++index){
214  if (isVertex(x,y,z,npts))
215  {
216  vertex.push_back(index);
217  }
218  else if (isEdge(x,y,z,npts))
219  {
220  if (isEdge_01(x,y,z,npts))
221  {
222  iEdge_01.push_back(index);
223  }
224  else if (isEdge_12(x,y,z,npts))
225  {
226  iEdge_12.push_back(index);
227  }
228  else if (isEdge_23(x,y,z,npts))
229  {
230  iEdge_23.push_back(index);
231  }
232  else if (isEdge_30(x,y,z,npts))
233  {
234  iEdge_30.push_back(index);
235  }
236  else if (isEdge_04(x,y,z,npts))
237  {
238  iEdge_04.push_back(index);
239  }
240  else if (isEdge_14(x,y,z,npts))
241  {
242  iEdge_14.push_back(index);
243  }
244  else if (isEdge_25(x,y,z,npts))
245  {
246  iEdge_25.push_back(index);
247  }
248  else if (isEdge_35(x,y,z,npts))
249  {
250  iEdge_35.push_back(index);
251  }
252  else if (isEdge_45(x,y,z,npts))
253  {
254  iEdge_45.push_back(index);
255  }
256  }
257  else if (isFace(x,y,z,npts))
258  {
259  if (isFace_0123(x,y,z,npts))
260  {
261  iFace_0123.push_back(index);
262  }
263  else if (isFace_014(x,y,z,npts))
264  {
265  iFace_014.push_back(index);
266  }
267  else if (isFace_1254(x,y,z,npts))
268  {
269  iFace_1254.push_back(index);
270  }
271  else if (isFace_325(x,y,z,npts))
272  {
273  iFace_325.push_back(index);
274  }
275  else if (isFace_0354(x,y,z,npts))
276  {
277  iFace_0354.push_back(index);
278  }
279  }
280  else
281  {
282  interiorVolumePoints.push_back(index);
283  }
284  }
285  }
286  }
287 
288  for (unsigned int n=0; n<vertex.size(); ++n)
289  {
290  map.push_back(vertex[n]);
291  }
292 
293  for (unsigned int n=0; n<iEdge_01.size(); ++n)
294  {
295  map.push_back(iEdge_01[n]);
296  }
297 
298  for (unsigned int n=0; n<iEdge_12.size(); ++n)
299  {
300  map.push_back(iEdge_12[n]);
301  }
302 
303  for (unsigned int n=0; n<iEdge_23.size(); ++n)
304  {
305  map.push_back(iEdge_23[n]);
306  }
307 
308  for (unsigned int n=0; n<iEdge_30.size(); ++n)
309  {
310  map.push_back(iEdge_30[n]);
311  }
312 
313  for (unsigned int n=0; n<iEdge_04.size(); ++n)
314  {
315  map.push_back(iEdge_04[n]);
316  }
317 
318  for (unsigned int n=0; n<iEdge_14.size(); ++n)
319  {
320  map.push_back(iEdge_14[n]);
321  }
322 
323  for (unsigned int n=0; n<iEdge_25.size(); ++n)
324  {
325  map.push_back(iEdge_25[n]);
326  }
327 
328  for (unsigned int n=0; n<iEdge_35.size(); ++n)
329  {
330  map.push_back(iEdge_35[n]);
331  }
332 
333  for (unsigned int n=0; n<iEdge_45.size(); ++n)
334  {
335  map.push_back(iEdge_45[n]);
336  }
337 
338  for (unsigned int n=0; n<iFace_0123.size(); ++n)
339  {
340  map.push_back(iFace_0123[n]);
341  }
342 
343  for (unsigned int n=0; n<iFace_014.size(); ++n)
344  {
345  map.push_back(iFace_014[n]);
346  }
347 
348  for(unsigned int n=0; n<iFace_1254.size(); ++n)
349  {
350  map.push_back(iFace_1254[n]);
351  }
352 
353  for(unsigned int n=0; n<iFace_325.size(); ++n)
354  {
355  map.push_back(iFace_325[n]);
356  }
357 
358  for(unsigned int n=0; n<iFace_0354.size(); ++n)
359  {
360  map.push_back(iFace_0354[n]);
361  }
362 
363  for(unsigned int n=0; n<interiorVolumePoints.size(); ++n)
364  {
365  map.push_back(interiorVolumePoints[n]);
366  }
367 
368  Array<OneD, NekDouble> points[3];
372 
373  for(unsigned int index=0; index<map.size(); ++index)
374  {
375  points[0][index] = m_points[0][index];
376  points[1][index] = m_points[1][index];
377  points[2][index] = m_points[2][index];
378  }
379 
380  for(unsigned int index=0; index<map.size(); ++index)
381  {
382  m_points[0][index] = points[0][map[index]];
383  m_points[1][index] = points[1][map[index]];
384  m_points[2][index] = points[2][map[index]];
385  }
386  }
387 
389  {
390  // Allocate the storage for points
392 
393  typedef DataType T;
394 
395  // Solve the Vandermonde system of integrals for the weight vector
396  NekVector<T> w = m_util->GetWeights();
397 
398  m_weights = Array<OneD,T>( w.GetRows(), w.GetPtr() );
399  }
400 
401 
402  // ////////////////////////////////////////
403  // CalculateInterpMatrix()
405  const Array<OneD, const NekDouble>& yia,
406  const Array<OneD, const NekDouble>& zia,
407  Array<OneD, NekDouble>& interp)
408  {
410  xi[0] = xia;
411  xi[1] = yia;
412  xi[2] = zia;
413 
414  std::shared_ptr<NekMatrix<NekDouble> > mat =
415  m_util->GetInterpolationMatrix(xi);
416  Vmath::Vcopy(mat->GetRows() * mat->GetColumns(), mat->GetRawPtr(),
417  1, &interp[0], 1);
418  }
419 
420  // ////////////////////////////////////////
421  // CalculateDerivMatrix()
423  {
424  // Allocate the derivative matrix.
426 
427  m_derivmatrix[0] = m_util->GetDerivMatrix(0);
428  m_derivmatrix[1] = m_util->GetDerivMatrix(1);
429  m_derivmatrix[2] = m_util->GetDerivMatrix(2);
430  }
431 
432  std::shared_ptr<PointsBaseType> NodalPrismEvenlySpaced::Create(const PointsKey &key)
433  {
434  std::shared_ptr<PointsBaseType> returnval(MemoryManager<NodalPrismEvenlySpaced>::AllocateSharedPtr(key));
435 
436  returnval->Initialize();
437 
438  return returnval;
439  }
440  } // end of namespace
441 } // end of namespace
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
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:390
MatrixSharedPtrType m_derivmatrix[3]
Derivative matrices.
Definition: Points.h:396
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:392
Defines a specification for a set of points.
Definition: Points.h:60
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:227
unsigned int GetRows() const
Definition: NekVector.cpp:215
PointsManagerT & PointsManager(void)
@ eNodalPrismEvenlySpaced
3D Evenly-spaced points on a Prism
Definition: PointsType.h:74
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
double NekDouble
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1199