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