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