Nektar++
HOAlignment.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: HOSAlignment.h
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: HO aligment routines.
32 //
33 ////////////////////////////////////////////////////////////////////////////////
34 
35 #ifndef NEKMESHUTILS_MESHELEMENTS_ALIGNMENT
36 #define NEKMESHUTILS_MESHELEMENTS_ALIGNMENT
37 
38 namespace Nektar
39 {
40 namespace NekMeshUtils
41 {
42 /**
43  * @brief A lightweight struct for dealing with high-order triangle
44  * alignment.
45  *
46  * The logic underlying these routines is taken from the original Nektar
47  * code.
48  */
49 template <typename T> struct HOTriangle
50 {
51  HOTriangle(std::vector<int> pVertId, std::vector<T> pSurfVerts)
52  : vertId(pVertId), surfVerts(pSurfVerts)
53  {
54  }
55  HOTriangle(std::vector<int> pVertId) : vertId(pVertId)
56  {
57  }
58 
59  /// The triangle vertex IDs
60  std::vector<int> vertId;
61 
62  /// The triangle surface vertices -- templated so that this can
63  /// either be nodes or IDs.
64  std::vector<T> surfVerts;
65 
66  /**
67  * @brief Rotates the triangle of data points inside #surfVerts
68  * counter-clockwise nrot times.
69  *
70  * @param nrot Number of times to rotate triangle.
71  */
72  void Rotate(int nrot)
73  {
74  int n, i, j, cnt;
75  int np = ((int)sqrt(8.0 * surfVerts.size() + 1.0) - 1) / 2;
76  std::vector<T> tmp(np * np);
77 
78  for (n = 0; n < nrot; ++n)
79  {
80  for (cnt = i = 0; i < np; ++i)
81  {
82  for (j = 0; j < np - i; ++j, cnt++)
83  {
84  tmp[i * np + j] = surfVerts[cnt];
85  }
86  }
87  for (cnt = i = 0; i < np; ++i)
88  {
89  for (j = 0; j < np - i; ++j, cnt++)
90  {
91  surfVerts[cnt] = tmp[(np - 1 - i - j) * np + i];
92  }
93  }
94  }
95  }
96 
97  /**
98  * @brief Reflect data points inside #surfVerts.
99  *
100  * This applies a mapping essentially doing the following
101  * reordering:
102  *
103  * 9 9
104  * 7 8 -> 8 7
105  * 4 5 6 6 5 4
106  * 0 1 2 3 3 2 1 0
107  */
108  void Reflect()
109  {
110  int i, j, cnt;
111  int np = ((int)sqrt(8.0 * surfVerts.size() + 1.0) - 1) / 2;
112  std::vector<T> tmp(np * np);
113 
114  for (cnt = i = 0; i < np; ++i)
115  {
116  for (j = 0; j < np - i; ++j, cnt++)
117  {
118  tmp[i * np + np - i - 1 - j] = surfVerts[cnt];
119  }
120  }
121 
122  for (cnt = i = 0; i < np; ++i)
123  {
124  for (j = 0; j < np - i; ++j, cnt++)
125  {
126  surfVerts[cnt] = tmp[i * np + j];
127  }
128  }
129  }
130 
131  /**
132  * @brief Align this surface to a given vertex ID.
133  */
134  void Align(std::vector<int> vertId)
135  {
136  if (vertId[0] == this->vertId[0])
137  {
138  if (vertId[1] == this->vertId[1] || vertId[1] == this->vertId[2])
139  {
140  if (vertId[1] == this->vertId[2])
141  {
142  Rotate(1);
143  Reflect();
144  }
145  }
146  }
147  else if (vertId[0] == this->vertId[1])
148  {
149  if (vertId[1] == this->vertId[0] || vertId[1] == this->vertId[2])
150  {
151  if (vertId[1] == this->vertId[0])
152  {
153  Reflect();
154  }
155  else
156  {
157  Rotate(2);
158  }
159  }
160  }
161  else if (vertId[0] == this->vertId[2])
162  {
163  if (vertId[1] == this->vertId[0] || vertId[1] == this->vertId[1])
164  {
165  if (vertId[1] == this->vertId[1])
166  {
167  Rotate(2);
168  Reflect();
169  }
170  else
171  {
172  Rotate(1);
173  }
174  }
175  }
176  }
177 };
178 
180 typedef std::shared_ptr<HOSurf> HOSurfSharedPtr;
181 
182 /**
183  * Hash class for high-order surfaces.
184  */
185 struct HOSurfHash : std::unary_function<HOSurfSharedPtr, std::size_t>
186 {
187  /**
188  * Calculate hash of a given high-order surface p by taking
189  * successive hashes of the vertex IDs.
190  */
191  std::size_t operator()(HOSurfSharedPtr const &p) const
192  {
193  std::vector<int> ids = p->vertId;
194  std::sort(ids.begin(), ids.end());
195  return hash_range(ids.begin(), ids.end());
196  }
197 };
198 
199 NEKMESHUTILS_EXPORT bool operator==(HOSurfSharedPtr const &p1,
200  HOSurfSharedPtr const &p2);
201 
202 typedef std::unordered_set<HOSurfSharedPtr, HOSurfHash> HOSurfSet;
203 
204 /**
205  * @brief A lightweight struct for dealing with high-order quadrilateral
206  * alignment.
207  */
208 template <typename T> struct HOQuadrilateral
209 {
210  HOQuadrilateral(std::vector<int> pVertId, std::vector<T> pSurfVerts)
211  : vertId(pVertId), surfVerts(pSurfVerts)
212  {
213  }
214 
215  HOQuadrilateral(std::vector<int> pVertId) : vertId(pVertId)
216  {
217  }
218 
219  /// The quadrilateral vertex IDs
220  std::vector<int> vertId;
221 
222  /// The quadrilateral surface vertices -- templated so that this can either
223  /// be nodes or IDs.
224  std::vector<T> surfVerts;
225 
226  void ReverseX()
227  {
228  int np = (int)(sqrt((NekDouble)surfVerts.size()) + 0.5);
229  for (int i = 0; i < np; ++i)
230  {
231  for (int j = 0; j < np/2; ++j)
232  {
233  swap(surfVerts[i*np + j], surfVerts[i*np + np-j-1]);
234  }
235  }
236  }
237 
238  void ReverseY()
239  {
240  int np = (int)(sqrt((NekDouble)surfVerts.size()) + 0.5);
241  // Reverse y direction
242  for (int j = 0; j < np; ++j)
243  {
244  for (int i = 0; i < np/2; ++i)
245  {
246  swap(surfVerts[i*np + j], surfVerts[(np-i-1)*np + j]);
247  }
248  }
249  }
250 
251  void Transpose()
252  {
253  int np = (int)(sqrt((NekDouble)surfVerts.size()) + 0.5);
254  std::vector<T> tmp(surfVerts.size());
255 
256  for (int i = 0; i < np; ++i)
257  {
258  for (int j = 0; j < np; ++j)
259  {
260  tmp[i*np+j] = surfVerts[j*np+i];
261  }
262  }
263 
264  surfVerts = tmp;
265  }
266 
267  /**
268  * @brief Align this surface to a given vertex ID.
269  */
270  void Align(std::vector<int> vertId)
271  {
272 
273  int vmap[4] = {-1, -1, -1, -1};
274 
275  // Determine which vertices map to vertId
276  for (int i = 0; i < 4; ++i)
277  {
278  for (int j = 0; j < 4; ++j)
279  {
280  if (this->vertId[j] == vertId[i])
281  {
282  vmap[i] = j;
283  break;
284  }
285  }
286 
287  ASSERTL1(vmap[i] != -1,
288  "Could not determine mapping between vertex IDs");
289  }
290 
292 
293  if (vmap[1] == (vmap[0]+1) % 4)
294  {
295  switch (vmap[0])
296  {
297  case 0:
299  break;
300  case 1:
302  break;
303  case 2:
305  break;
306  case 3:
308  break;
309  }
310  }
311  else
312  {
313  switch (vmap[0])
314  {
315  case 0:
317  break;
318  case 1:
320  break;
321  case 2:
323  break;
324  case 3:
326  break;
327  }
328  }
329 
330  if (orient == StdRegions::eDir1FwdDir2_Dir2FwdDir1 ||
334  {
335  Transpose();
336  }
337 
338  if (orient == StdRegions::eDir1BwdDir1_Dir2FwdDir2 ||
342  {
343  ReverseX();
344  }
345 
346  if (orient == StdRegions::eDir1FwdDir1_Dir2BwdDir2 ||
350  {
351  ReverseY();
352  }
353  }
354 };
355 
356 }
357 }
358 #endif
std::size_t hash_range(Iter first, Iter last)
Definition: HashUtils.hpp:69
std::unordered_set< HOSurfSharedPtr, HOSurfHash > HOSurfSet
Definition: HOAlignment.h:202
void Align(std::vector< int > vertId)
Align this surface to a given vertex ID.
Definition: HOAlignment.h:134
std::vector< T > surfVerts
The quadrilateral surface vertices – templated so that this can either be nodes or IDs...
Definition: HOAlignment.h:224
std::vector< int > vertId
The quadrilateral vertex IDs.
Definition: HOAlignment.h:220
std::vector< T > surfVerts
The triangle surface vertices – templated so that this can either be nodes or IDs.
Definition: HOAlignment.h:64
std::vector< int > vertId
The triangle vertex IDs.
Definition: HOAlignment.h:60
void Rotate(int nrot)
Rotates the triangle of data points inside surfVerts counter-clockwise nrot times.
Definition: HOAlignment.h:72
HOQuadrilateral(std::vector< int > pVertId)
Definition: HOAlignment.h:215
bool operator==(ElmtConfig const &c1, ElmtConfig const &c2)
Compares two element config structs.
std::size_t operator()(HOSurfSharedPtr const &p) const
Definition: HOAlignment.h:191
HOTriangle(std::vector< int > pVertId)
Definition: HOAlignment.h:55
NekMatrix< InnerMatrixType, BlockMatrixTag > Transpose(NekMatrix< InnerMatrixType, BlockMatrixTag > &rhs)
double NekDouble
void Align(std::vector< int > vertId)
Align this surface to a given vertex ID.
Definition: HOAlignment.h:270
A lightweight struct for dealing with high-order triangle alignment.
Definition: HOAlignment.h:49
A lightweight struct for dealing with high-order quadrilateral alignment.
Definition: HOAlignment.h:208
#define NEKMESHUTILS_EXPORT
std::shared_ptr< HOSurf > HOSurfSharedPtr
Definition: HOAlignment.h:180
HOQuadrilateral(std::vector< int > pVertId, std::vector< T > pSurfVerts)
Definition: HOAlignment.h:210
void Reflect()
Reflect data points inside surfVerts.
Definition: HOAlignment.h:108
HOTriangle(std::vector< int > pVertId, std::vector< T > pSurfVerts)
Definition: HOAlignment.h:51
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
HOTriangle< NodeSharedPtr > HOSurf
Definition: HOAlignment.h:179