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