Nektar++
NodalTriFekete.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: NodalTriFekete.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: 2D Nodal Triangle Fekete Point Definitions
32//
33///////////////////////////////////////////////////////////////////////////////
34
37
39{
42
43// ////////////////////////////////////////////////////////
44// Coordinate the nodal trianlge Fekete points
46{
47 // Allocate the storage for points
49
50 size_t index = 0, isum = 0;
51 const size_t offset = 3; // offset to match Datafile
52 NekDouble b, c;
53 size_t numPoints = GetNumPoints();
54
55 // initialize values
56 for (size_t i = 0; i < numPoints - 2; ++i)
57 {
58 index += NodalTriFeketeNPTS[i];
59 }
60
61 for (size_t i = 0; i < NodalTriFeketeNPTS[numPoints - 2]; ++i, ++index)
62 {
63 if (int(NodalTriFeketeData[index][0]))
64 {
65 b = NodalTriFeketeData[index][4];
66 c = NodalTriFeketeData[index][5];
67
68 m_points[0][isum] = 2.0 * b - 1.0;
69 m_points[1][isum] = 2.0 * c - 1.0;
70 isum++;
71 continue;
72 } // end symmetry1
73
74 if (int(NodalTriFeketeData[index][1]) == 1)
75 {
76 for (size_t j = 0; j < 3; ++j)
77 {
78 b = NodalTriFeketeData[index][offset + perm3A_2d[j][1]];
79 c = NodalTriFeketeData[index][offset + perm3A_2d[j][2]];
80 m_points[0][isum] = 2.0 * b - 1.0;
81 m_points[1][isum] = 2.0 * c - 1.0;
82 isum++;
83 } // end j
84 continue;
85 } // end symmetry3a
86
87 if (int(NodalTriFeketeData[index][1]) == 2)
88 {
89 for (size_t j = 0; j < 3; ++j)
90 {
91 b = NodalTriFeketeData[index][offset + perm3B_2d[j][1]];
92 c = NodalTriFeketeData[index][offset + perm3B_2d[j][2]];
93 m_points[0][isum] = 2.0 * b - 1.0;
94 m_points[1][isum] = 2.0 * c - 1.0;
95 isum++;
96 } // end j
97 continue;
98 } // end symmetry3b
99
100 if (int(NodalTriFeketeData[index][2]))
101 {
102 for (size_t j = 0; j < 6; ++j)
103 {
104 b = NodalTriFeketeData[index][offset + perm6_2d[j][1]];
105 c = NodalTriFeketeData[index][offset + perm6_2d[j][2]];
106 m_points[0][isum] = 2.0 * b - 1.0;
107 m_points[1][isum] = 2.0 * c - 1.0;
108 isum++;
109 } // end j
110 continue;
111 } // end symmetry6
112 } // end npts
113
115
116 ASSERTL1((static_cast<size_t>(isum) == m_pointsKey.GetTotNumPoints()),
117 "sum not equal to npts");
118
120 numPoints - 1, m_points[0], m_points[1]);
121}
122
124{
125 // Allocate the storage for points
127
128 typedef DataType T;
129
130 // Solve the Vandermonde system of integrals for the weight vector
131 NekVector<T> w = m_util->GetWeights();
132 m_weights = Array<OneD, T>(w.GetRows(), w.GetPtr());
133}
134
135// ////////////////////////////////////////
136// CalculateInterpMatrix()
140{
142 xi[0] = xia;
143 xi[1] = yia;
144
145 std::shared_ptr<NekMatrix<NekDouble>> mat =
146 m_util->GetInterpolationMatrix(xi);
147 Vmath::Vcopy(mat->GetRows() * mat->GetColumns(), mat->GetRawPtr(), 1,
148 &interp[0], 1);
149}
150
151// ////////////////////////////////////////
152// CalculateDerivMatrix()
154{
155 // Allocate the derivative matrix.
156 PointsBaseType::v_CalculateDerivMatrix();
157
158 m_derivmatrix[0] = m_util->GetDerivMatrix(0);
159 m_derivmatrix[1] = m_util->GetDerivMatrix(1);
160}
161
162std::shared_ptr<PointsBaseType> NodalTriFekete::Create(const PointsKey &key)
163{
164 std::shared_ptr<PointsBaseType> returnval(
166 returnval->Initialize();
167 return returnval;
168}
169
171{
172 size_t i, j;
173 size_t cnt;
174 size_t istart, iend;
175
176 const size_t nVerts = 3;
177 const size_t nEdgeInteriorPoints = GetNumPoints() - 2;
178 const size_t nBoundaryPoints = 3 * nEdgeInteriorPoints + 3;
179
180 if (nEdgeInteriorPoints == 0)
181 {
182 return;
183 }
184
185 // group the points of edge 1 together;
186 istart = nVerts;
187 for (i = cnt = istart; i < nBoundaryPoints; i++)
188 {
189 if (fabs(m_points[1][i] + 1.0) < NekConstants::kNekZeroTol)
190 {
191 std::swap(m_points[0][cnt], m_points[0][i]);
192 std::swap(m_points[1][cnt], m_points[1][i]);
193 cnt++;
194 }
195 }
196
197 // bubble sort edge 1 (counterclockwise numbering)
198 iend = istart + nEdgeInteriorPoints;
199 for (i = istart; i < iend; i++)
200 {
201 for (j = istart + 1; j < iend; j++)
202 {
203 if (m_points[0][j] < m_points[0][j - 1])
204 {
205 std::swap(m_points[0][j], m_points[0][j - 1]);
206 std::swap(m_points[1][j], m_points[1][j - 1]);
207 }
208 }
209 }
210
211 // group the points of edge 2 together;
212 istart = iend;
213 for (i = cnt = istart; i < nBoundaryPoints; i++)
214 {
215 if (fabs(m_points[1][i] + m_points[0][i]) < NekConstants::kNekZeroTol)
216 {
217 std::swap(m_points[0][cnt], m_points[0][i]);
218 std::swap(m_points[1][cnt], m_points[1][i]);
219 cnt++;
220 }
221 }
222
223 // bubble sort edge 2 (counterclockwise numbering)
224 iend = istart + nEdgeInteriorPoints;
225 for (i = istart; i < iend; i++)
226 {
227 for (j = istart + 1; j < iend; j++)
228 {
229 if (m_points[1][j] < m_points[1][j - 1])
230 {
231 std::swap(m_points[0][j], m_points[0][j - 1]);
232 std::swap(m_points[1][j], m_points[1][j - 1]);
233 }
234 }
235 }
236
237 // group the points of edge 3 together;
238 istart = iend;
239 for (i = cnt = istart; i < nBoundaryPoints; i++)
240 {
241 if (fabs(m_points[0][i] + 1.0) < NekConstants::kNekZeroTol)
242 {
243 std::swap(m_points[0][cnt], m_points[0][i]);
244 std::swap(m_points[1][cnt], m_points[1][i]);
245 cnt++;
246 }
247 }
248 // bubble sort edge 3 (counterclockwise numbering)
249 iend = istart + nEdgeInteriorPoints;
250 for (i = istart; i < iend; i++)
251 {
252 for (j = istart + 1; j < iend; j++)
253 {
254 if (m_points[1][j] > m_points[1][j - 1])
255 {
256 std::swap(m_points[0][j], m_points[0][j - 1]);
257 std::swap(m_points[1][j], m_points[1][j - 1]);
258 }
259 }
260 }
261
262 if (GetNumPoints() < 5)
263 {
264 // at numpoints = 4 there is only one interior point so doesnt
265 // need sorting
266 return;
267 }
268
269 // someone forgot to finish this piece of code and tell anyone
270 // that they didnt
271 // face interior nodes needs to be considered
272 // make a copy of the unsorted nodes
273 // bubble sort by smallest y
274 // which will put them into sets of ever decreasing size
275 // which can be bubble sorted by x to obtain the distrobution
276
277 Array<OneD, NekDouble> xc(m_points[0].size() - iend);
278 Array<OneD, NekDouble> yc(m_points[0].size() - iend);
279 size_t ct = 0;
280 for (i = iend; i < m_points[0].size(); i++, ct++)
281 {
282 xc[ct] = m_points[0][i];
283 yc[ct] = m_points[1][i];
284 }
285
286 // sort smallest first
287 bool repeat = true;
288 while (repeat)
289 {
290 repeat = false;
291 for (i = 0; i < xc.size() - 1; i++)
292 {
293 if (yc[i] > yc[i + 1])
294 {
295 std::swap(xc[i], xc[i + 1]);
296 std::swap(yc[i], yc[i + 1]);
297 repeat = true;
298 }
299 }
300 }
301
302 size_t offset = 0;
303 size_t npl = GetNumPoints() - 3;
304 while (npl > 1)
305 {
306 repeat = true;
307 while (repeat)
308 {
309 repeat = false;
310 for (i = offset; i < offset + npl - 1; i++)
311 {
312 if (xc[i] > xc[i + 1])
313 {
314 std::swap(xc[i], xc[i + 1]);
315 std::swap(yc[i], yc[i + 1]);
316 repeat = true;
317 }
318 }
319 }
320 offset += npl;
321 npl--;
322 }
323
324 // copy back in
325 ct = 0;
326 for (i = iend; i < m_points[0].size(); i++, ct++)
327 {
328 m_points[0][i] = xc[ct];
329 m_points[1][i] = yc[ct];
330 }
331 return;
332}
333
334} // namespace Nektar::LibUtilities
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:242
size_type size() const
Returns the array's size.
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
void CalculateInterpMatrix(const Array< OneD, const NekDouble > &xi, const Array< OneD, const NekDouble > &yi, Array< OneD, NekDouble > &interp)
std::shared_ptr< NodalUtilTriangle > m_util
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
PointsKey m_pointsKey
Points type for this points distributions.
Definition: Points.h:353
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
size_t GetTotNumPoints() const
Definition: Points.h:158
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.
static const size_t perm3A_2d[3][3]
PointsManagerT & PointsManager(void)
static const size_t perm6_2d[6][3]
static const NekDouble NodalTriFeketeData[][6]
static const size_t NodalTriFeketeNPTS[NodalTriFeketeAvailable]
@ eNodalTriFekete
2D Nodal Fekete Points on a Triangle
Definition: PointsType.h:82
static const size_t perm3B_2d[3][3]
static const NekDouble kNekZeroTol
std::vector< double > w(NPUPPER)
double NekDouble
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.hpp:825