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