Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: HO aligment routines.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #ifndef NEKMESHUTILS_MESHELEMENTS_ALIGNMENT
37 #define NEKMESHUTILS_MESHELEMENTS_ALIGNMENT
38 
39 namespace Nektar
40 {
41 namespace NekMeshUtils
42 {
43 /**
44  * @brief A lightweight struct for dealing with high-order triangle
45  * alignment.
46  *
47  * The logic underlying these routines is taken from the original Nektar
48  * code.
49  */
50 template <typename T> struct HOTriangle
51 {
52  HOTriangle(std::vector<int> pVertId, std::vector<T> pSurfVerts)
53  : vertId(pVertId), surfVerts(pSurfVerts)
54  {
55  }
56  HOTriangle(std::vector<int> pVertId) : vertId(pVertId)
57  {
58  }
59 
60  /// The triangle vertex IDs
61  std::vector<int> vertId;
62 
63  /// The triangle surface vertices -- templated so that this can
64  /// either be nodes or IDs.
65  std::vector<T> surfVerts;
66 
67  /**
68  * @brief Rotates the triangle of data points inside #surfVerts
69  * counter-clockwise nrot times.
70  *
71  * @param nrot Number of times to rotate triangle.
72  */
73  void Rotate(int nrot)
74  {
75  int n, i, j, cnt;
76  int np = ((int)sqrt(8.0 * surfVerts.size() + 1.0) - 1) / 2;
77  std::vector<T> tmp(np * np);
78 
79  for (n = 0; n < nrot; ++n)
80  {
81  for (cnt = i = 0; i < np; ++i)
82  {
83  for (j = 0; j < np - i; ++j, cnt++)
84  {
85  tmp[i * np + j] = surfVerts[cnt];
86  }
87  }
88  for (cnt = i = 0; i < np; ++i)
89  {
90  for (j = 0; j < np - i; ++j, cnt++)
91  {
92  surfVerts[cnt] = tmp[(np - 1 - i - j) * np + i];
93  }
94  }
95  }
96  }
97 
98  /**
99  * @brief Reflect data points inside #surfVerts.
100  *
101  * This applies a mapping essentially doing the following
102  * reordering:
103  *
104  * 9 9
105  * 7 8 -> 8 7
106  * 4 5 6 6 5 4
107  * 0 1 2 3 3 2 1 0
108  */
109  void Reflect()
110  {
111  int i, j, cnt;
112  int np = ((int)sqrt(8.0 * surfVerts.size() + 1.0) - 1) / 2;
113  std::vector<T> tmp(np * np);
114 
115  for (cnt = i = 0; i < np; ++i)
116  {
117  for (j = 0; j < np - i; ++j, cnt++)
118  {
119  tmp[i * np + np - i - 1 - j] = surfVerts[cnt];
120  }
121  }
122 
123  for (cnt = i = 0; i < np; ++i)
124  {
125  for (j = 0; j < np - i; ++j, cnt++)
126  {
127  surfVerts[cnt] = tmp[i * np + j];
128  }
129  }
130  }
131 
132  /**
133  * @brief Align this surface to a given vertex ID.
134  */
135  void Align(std::vector<int> vertId)
136  {
137  if (vertId[0] == this->vertId[0])
138  {
139  if (vertId[1] == this->vertId[1] || vertId[1] == this->vertId[2])
140  {
141  if (vertId[1] == this->vertId[2])
142  {
143  Rotate(1);
144  Reflect();
145  }
146  }
147  }
148  else if (vertId[0] == this->vertId[1])
149  {
150  if (vertId[1] == this->vertId[0] || vertId[1] == this->vertId[2])
151  {
152  if (vertId[1] == this->vertId[0])
153  {
154  Reflect();
155  }
156  else
157  {
158  Rotate(2);
159  }
160  }
161  }
162  else if (vertId[0] == this->vertId[2])
163  {
164  if (vertId[1] == this->vertId[0] || vertId[1] == this->vertId[1])
165  {
166  if (vertId[1] == this->vertId[1])
167  {
168  Rotate(2);
169  Reflect();
170  }
171  else
172  {
173  Rotate(1);
174  }
175  }
176  }
177  }
178 };
179 
181 typedef boost::shared_ptr<HOSurf> HOSurfSharedPtr;
182 
183 /**
184  * Hash class for high-order surfaces.
185  */
186 struct HOSurfHash : std::unary_function<HOSurfSharedPtr, std::size_t>
187 {
188  /**
189  * Calculate hash of a given high-order surface p by taking
190  * successive hashes of the vertex IDs.
191  */
192  std::size_t operator()(HOSurfSharedPtr const &p) const
193  {
194  std::size_t seed = 0;
195  std::vector<int> ids = p->vertId;
196 
197  std::sort(ids.begin(), ids.end());
198  for (int i = 0; i < ids.size(); ++i)
199  {
200  boost::hash_combine(seed, ids[i]);
201  }
202  return seed;
203  }
204 };
205 
206 NEKMESHUTILS_EXPORT bool operator==(HOSurfSharedPtr const &p1,
207  HOSurfSharedPtr const &p2);
208 
209 typedef boost::unordered_set<HOSurfSharedPtr, HOSurfHash> HOSurfSet;
210 
211 /**
212  * @brief A lightweight struct for dealing with high-order quadrilateral
213  * alignment.
214  */
215 template <typename T> struct HOQuadrilateral
216 {
217  HOQuadrilateral(std::vector<int> pVertId, std::vector<T> pSurfVerts)
218  : vertId(pVertId), surfVerts(pSurfVerts)
219  {
220  }
221 
222  HOQuadrilateral(std::vector<int> pVertId) : vertId(pVertId)
223  {
224  }
225 
226  /// The quadrilateral vertex IDs
227  std::vector<int> vertId;
228 
229  /// The quadrilateral surface vertices -- templated so that this can either
230  /// be nodes or IDs.
231  std::vector<T> surfVerts;
232 
233  void ReverseX()
234  {
235  int np = (int)(sqrt((NekDouble)surfVerts.size()) + 0.5);
236  for (int i = 0; i < np; ++i)
237  {
238  for (int j = 0; j < np/2; ++j)
239  {
240  swap(surfVerts[i*np + j], surfVerts[i*np + np-j-1]);
241  }
242  }
243  }
244 
245  void ReverseY()
246  {
247  int np = (int)(sqrt((NekDouble)surfVerts.size()) + 0.5);
248  // Reverse y direction
249  for (int j = 0; j < np; ++j)
250  {
251  for (int i = 0; i < np/2; ++i)
252  {
253  swap(surfVerts[i*np + j], surfVerts[(np-i-1)*np + j]);
254  }
255  }
256  }
257 
258  void Transpose()
259  {
260  int np = (int)(sqrt((NekDouble)surfVerts.size()) + 0.5);
261  std::vector<T> tmp(surfVerts.size());
262 
263  for (int i = 0; i < np; ++i)
264  {
265  for (int j = 0; j < np; ++j)
266  {
267  tmp[i*np+j] = surfVerts[j*np+i];
268  }
269  }
270 
271  surfVerts = tmp;
272  }
273 
274  /**
275  * @brief Align this surface to a given vertex ID.
276  */
277  void Align(std::vector<int> vertId)
278  {
279 
280  int vmap[4] = {-1, -1, -1, -1};
281 
282  // Determine which vertices map to vertId
283  for (int i = 0; i < 4; ++i)
284  {
285  for (int j = 0; j < 4; ++j)
286  {
287  if (this->vertId[j] == vertId[i])
288  {
289  vmap[i] = j;
290  break;
291  }
292  }
293 
294  ASSERTL1(vmap[i] != -1,
295  "Could not determine mapping between vertex IDs");
296  }
297 
299 
300  if (vmap[1] == (vmap[0]+1) % 4)
301  {
302  switch (vmap[0])
303  {
304  case 0:
306  break;
307  case 1:
309  break;
310  case 2:
312  break;
313  case 3:
315  break;
316  }
317  }
318  else
319  {
320  switch (vmap[0])
321  {
322  case 0:
324  break;
325  case 1:
327  break;
328  case 2:
330  break;
331  case 3:
333  break;
334  }
335  }
336 
337  if (orient == StdRegions::eDir1FwdDir2_Dir2FwdDir1 ||
341  {
342  Transpose();
343  }
344 
345  if (orient == StdRegions::eDir1BwdDir1_Dir2FwdDir2 ||
349  {
350  ReverseX();
351  }
352 
353  if (orient == StdRegions::eDir1FwdDir1_Dir2BwdDir2 ||
357  {
358  ReverseY();
359  }
360  }
361 };
362 
363 }
364 }
365 #endif
boost::unordered_set< HOSurfSharedPtr, HOSurfHash > HOSurfSet
Definition: HOAlignment.h:209
void Align(std::vector< int > vertId)
Align this surface to a given vertex ID.
Definition: HOAlignment.h:135
std::vector< T > surfVerts
The quadrilateral surface vertices – templated so that this can either be nodes or IDs...
Definition: HOAlignment.h:231
boost::shared_ptr< HOSurf > HOSurfSharedPtr
Definition: HOAlignment.h:181
std::vector< int > vertId
The quadrilateral vertex IDs.
Definition: HOAlignment.h:227
std::size_t operator()(HOSurfSharedPtr const &p) const
Definition: HOAlignment.h:192
std::vector< T > surfVerts
The triangle surface vertices – templated so that this can either be nodes or IDs.
Definition: HOAlignment.h:65
std::vector< int > vertId
The triangle vertex IDs.
Definition: HOAlignment.h:61
void Rotate(int nrot)
Rotates the triangle of data points inside surfVerts counter-clockwise nrot times.
Definition: HOAlignment.h:73
HOQuadrilateral(std::vector< int > pVertId)
Definition: HOAlignment.h:222
bool operator==(ElmtConfig const &c1, ElmtConfig const &c2)
Compares two element config structs.
HOTriangle(std::vector< int > pVertId)
Definition: HOAlignment.h:56
double NekDouble
void Align(std::vector< int > vertId)
Align this surface to a given vertex ID.
Definition: HOAlignment.h:277
A lightweight struct for dealing with high-order triangle alignment.
Definition: HOAlignment.h:50
A lightweight struct for dealing with high-order quadrilateral alignment.
Definition: HOAlignment.h:215
#define NEKMESHUTILS_EXPORT
HOQuadrilateral(std::vector< int > pVertId, std::vector< T > pSurfVerts)
Definition: HOAlignment.h:217
void Reflect()
Reflect data points inside surfVerts.
Definition: HOAlignment.h:109
HOTriangle(std::vector< int > pVertId, std::vector< T > pSurfVerts)
Definition: HOAlignment.h:52
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:228
HOTriangle< NodeSharedPtr > HOSurf
Definition: HOAlignment.h:180