Nektar++
Octant.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: Octant.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: octant object methods.
32 //
33 ////////////////////////////////////////////////////////////////////////////////
34 
36 
37 using namespace std;
38 namespace Nektar
39 {
40 namespace NekMeshUtils
41 {
42 
44 {
45  switch (f)
46  {
47  case eUp:
48  return eDown;
49  case eDown:
50  return eUp;
51  case eForward:
52  return eBack;
53  case eBack:
54  return eForward;
55  case eLeft:
56  return eRight;
57  case eRight:
58  return eLeft;
59  }
60 
61  return eUp;
62 }
63 
64 Octant::Octant(int i, OctantSharedPtr p, Array<OneD, OctantFace> dir)
65  : m_id(i), m_parent(p)
66 {
67  // initialise variables to defualt states
68  m_leaf = true;
69  m_needToDivide = false;
70  m_numValidPoints = 0;
72  m_delta = pair<bool, NekDouble>(false, 0.0);
73  NekDouble maxDif = 0;
74  NekDouble minDif = numeric_limits<double>::max();
76 
77  // build empty neigbour map
78  m_neigbours[eUp] = vector<OctantSharedPtr>();
79  m_neigbours[eDown] = vector<OctantSharedPtr>();
80  m_neigbours[eForward] = vector<OctantSharedPtr>();
81  m_neigbours[eBack] = vector<OctantSharedPtr>();
82  m_neigbours[eLeft] = vector<OctantSharedPtr>();
83  m_neigbours[eRight] = vector<OctantSharedPtr>();
84 
85  // pull information from parent
86  Array<OneD, NekDouble> parentloc = m_parent->GetLoc();
87  m_hd = m_parent->DX() / 2.0;
89  if (dir[0] == eForward)
90  {
91  m_loc[0] = parentloc[0] + m_hd;
92  }
93  else
94  {
95  m_loc[0] = parentloc[0] - m_hd;
96  }
97  if (dir[1] == eUp)
98  {
99  m_loc[1] = parentloc[1] + m_hd;
100  }
101  else
102  {
103  m_loc[1] = parentloc[1] - m_hd;
104  }
105  if (dir[2] == eLeft)
106  {
107  m_loc[2] = parentloc[2] + m_hd;
108  }
109  else
110  {
111  m_loc[2] = parentloc[2] - m_hd;
112  }
113 
114  vector<SPBaseSharedPtr> SourcePointList = m_parent->GetSPList();
115 
116  // setup complete
117 
118  // look over the curvature point list provided by the parent,
119  // firstly look to see if it is in the new octant and if so
120  // add it to the conserdation of the delta specification
121  for (int i = 0; i < SourcePointList.size(); i++)
122  {
123  Array<OneD, NekDouble> cploc = SourcePointList[i]->GetLoc();
124  if (!(cploc[0] > m_loc[0] + m_hd || cploc[0] < m_loc[0] - m_hd ||
125  cploc[1] > m_loc[1] + m_hd || cploc[1] < m_loc[1] - m_hd ||
126  cploc[2] > m_loc[2] + m_hd || cploc[2] < m_loc[2] - m_hd))
127  {
128  m_localSPList.push_back(SourcePointList[i]);
129 
130  if (SourcePointList[i]->HasDelta())
131  {
132  if (SourcePointList[i]->GetDelta() > maxDif)
133  {
134  maxDif = SourcePointList[i]->GetDelta();
135  }
136 
137  if (SourcePointList[i]->GetDelta() < minDif)
138  {
139  minDif = SourcePointList[i]->GetDelta();
140  }
142  }
143  if (SourcePointList[i]->Isboundary())
144  {
146  }
147  }
148  }
149 
150  // if it has valid points delta can be calculated
151  if (NumValidCurvePoint() > 0)
152  {
153  // geometrically octant should subdivide
154  if (maxDif / minDif > 1.5)
155  {
156  m_needToDivide = true;
157  }
158 
159  SetDelta(minDif);
160 
161  //encourage subdivision to keep spec smooth
162  if (GetDelta() < 5.0 * DX())
163  {
164  m_needToDivide = true;
165  }
166  }
167 
168  if (GetNumBoundary() > 0)
169  {
171  }
172 }
173 
174 // constructor for the master octant
176  NekDouble x,
177  NekDouble y,
178  NekDouble z,
179  NekDouble dx,
180  const vector<SPBaseSharedPtr> &splist)
181  : m_id(i), m_hd(dx)
182 {
183  m_neigbours[eUp] = vector<OctantSharedPtr>();
184  m_neigbours[eDown] = vector<OctantSharedPtr>();
185  m_neigbours[eForward] = vector<OctantSharedPtr>();
186  m_neigbours[eBack] = vector<OctantSharedPtr>();
187  m_neigbours[eLeft] = vector<OctantSharedPtr>();
188  m_neigbours[eRight] = vector<OctantSharedPtr>();
189 
190  // initialise variables to defualt states
191  m_leaf = true;
192  m_needToDivide = true;
193  m_numValidPoints = 0;
194  m_delta = pair<bool, NekDouble>(false, 0.0);
195 
197  m_loc[0] = x;
198  m_loc[1] = y;
199  m_loc[2] = z;
200 
201  m_localSPList = splist;
202 
203  for (int i = 0; i < m_localSPList.size(); i++)
204  {
205  if (m_localSPList[i]->HasDelta())
206  {
208  }
209  }
210 
212 }
213 
215 {
216  ASSERTL0(m_leaf, "octant must be a leaf for subdivision");
217 
218  m_leaf = false; // set as not leaf and make children
219 
220  // need to loop over all neigbours and remove this octant from their lists
221  for (int i = 0; i < 6; i++)
222  {
223  OctantFace f = static_cast<OctantFace>(i);
224  vector<OctantSharedPtr> os = m_neigbours[f];
225  for (int j = 0; j < os.size(); j++)
226  {
227  os[j]->RemoveNeigbour(GetId(), GetReverseFace(f));
228  }
229  }
230 
231  Array<OneD, OctantSharedPtr> children(8);
232 
233  for (int i = 0; i < 8; i++)
234  {
235  // set up x,y,z ordering of the 8 octants
237  if (i < 4)
238  {
239  dir[0] = eForward;
240  if (i < 2)
241  {
242  dir[1] = eUp;
243  }
244  else
245  {
246  dir[1] = eDown;
247  }
248  if (i == 0 || i == 2)
249  {
250  dir[2] = eLeft;
251  }
252  else
253  {
254  dir[2] = eRight;
255  }
256  }
257  else
258  {
259  dir[0] = eBack;
260  if (i < 6)
261  {
262  dir[1] = eUp;
263  }
264  else
265  {
266  dir[1] = eDown;
267  }
268  if (i == 4 || i == 6)
269  {
270  dir[2] = eLeft;
271  }
272  else
273  {
274  dir[2] = eRight;
275  }
276  }
277 
278  children[i] = std::shared_ptr<Octant>(new Octant(numoct++, p, dir));
279  }
280 
281  SetChildren(children);
282 
283  // this set of neibours are based on the children of the octant, only covers
284  // three sides
285  children[0]->SetNeigbour(children[1], eRight);
286  children[0]->SetNeigbour(children[4], eBack);
287  children[0]->SetNeigbour(children[2], eDown);
288 
289  children[1]->SetNeigbour(children[0], eLeft);
290  children[1]->SetNeigbour(children[5], eBack);
291  children[1]->SetNeigbour(children[3], eDown);
292 
293  children[2]->SetNeigbour(children[3], eRight);
294  children[2]->SetNeigbour(children[6], eBack);
295  children[2]->SetNeigbour(children[0], eUp);
296 
297  children[3]->SetNeigbour(children[2], eLeft);
298  children[3]->SetNeigbour(children[7], eBack);
299  children[3]->SetNeigbour(children[1], eUp);
300 
301  children[4]->SetNeigbour(children[5], eRight);
302  children[4]->SetNeigbour(children[0], eForward);
303  children[4]->SetNeigbour(children[6], eDown);
304 
305  children[5]->SetNeigbour(children[4], eLeft);
306  children[5]->SetNeigbour(children[1], eForward);
307  children[5]->SetNeigbour(children[7], eDown);
308 
309  children[6]->SetNeigbour(children[7], eRight);
310  children[6]->SetNeigbour(children[2], eForward);
311  children[6]->SetNeigbour(children[4], eUp);
312 
313  children[7]->SetNeigbour(children[6], eLeft);
314  children[7]->SetNeigbour(children[3], eForward);
315  children[7]->SetNeigbour(children[5], eUp);
316 
317  // need to obtain the remaning information from the parents neigbours
318  // (m_neigbours)
319  // consider top face
320  if (m_neigbours[eUp].size() == 1)
321  {
322  children[0]->SetNeigbour(m_neigbours[eUp][0], eUp);
323  children[1]->SetNeigbour(m_neigbours[eUp][0], eUp);
324  children[4]->SetNeigbour(m_neigbours[eUp][0], eUp);
325  children[5]->SetNeigbour(m_neigbours[eUp][0], eUp);
326  m_neigbours[eUp][0]->SetNeigbour(children[0], eDown);
327  m_neigbours[eUp][0]->SetNeigbour(children[1], eDown);
328  m_neigbours[eUp][0]->SetNeigbour(children[4], eDown);
329  m_neigbours[eUp][0]->SetNeigbour(children[5], eDown);
330  }
331  else if (m_neigbours[eUp].size() == 4)
332  {
333  children[0]->SetNeigbour(m_neigbours[eUp][0], eUp); // 2
334  children[1]->SetNeigbour(m_neigbours[eUp][1], eUp); // 3
335  children[4]->SetNeigbour(m_neigbours[eUp][2], eUp); // 6
336  children[5]->SetNeigbour(m_neigbours[eUp][3], eUp); // 7
337  m_neigbours[eUp][0]->SetNeigbour(children[0], eDown);
338  m_neigbours[eUp][1]->SetNeigbour(children[1], eDown);
339  m_neigbours[eUp][2]->SetNeigbour(children[4], eDown);
340  m_neigbours[eUp][3]->SetNeigbour(children[5], eDown);
341  }
342  else if (m_neigbours[eUp].size() != 0)
343  {
344  cout << "!!!!!"
345  << "NOT GOOD"
346  << "!!!!! " << m_neigbours[eUp].size() << endl;
347  }
348 
349  if (m_neigbours[eDown].size() == 1)
350  {
351  children[2]->SetNeigbour(m_neigbours[eDown][0], eDown);
352  children[3]->SetNeigbour(m_neigbours[eDown][0], eDown);
353  children[6]->SetNeigbour(m_neigbours[eDown][0], eDown);
354  children[7]->SetNeigbour(m_neigbours[eDown][0], eDown);
355  m_neigbours[eDown][0]->SetNeigbour(children[2], eUp);
356  m_neigbours[eDown][0]->SetNeigbour(children[3], eUp);
357  m_neigbours[eDown][0]->SetNeigbour(children[6], eUp);
358  m_neigbours[eDown][0]->SetNeigbour(children[7], eUp);
359  }
360  else if (m_neigbours[eDown].size() == 4)
361  {
362  children[2]->SetNeigbour(m_neigbours[eDown][0], eDown); // 0
363  children[3]->SetNeigbour(m_neigbours[eDown][1], eDown); // 1
364  children[6]->SetNeigbour(m_neigbours[eDown][2], eDown); // 4
365  children[7]->SetNeigbour(m_neigbours[eDown][3], eDown); // 5
366  m_neigbours[eDown][0]->SetNeigbour(children[2], eUp);
367  m_neigbours[eDown][1]->SetNeigbour(children[3], eUp);
368  m_neigbours[eDown][2]->SetNeigbour(children[6], eUp);
369  m_neigbours[eDown][3]->SetNeigbour(children[7], eUp);
370  }
371  else if (m_neigbours[eDown].size() != 0)
372  {
373  cout << "!!!!!"
374  << "NOT GOOD"
375  << "!!!!! " << m_neigbours[eDown].size() << endl;
376  }
377 
378  if (m_neigbours[eForward].size() == 1)
379  {
380  children[0]->SetNeigbour(m_neigbours[eForward][0], eForward);
381  children[1]->SetNeigbour(m_neigbours[eForward][0], eForward);
382  children[2]->SetNeigbour(m_neigbours[eForward][0], eForward);
383  children[3]->SetNeigbour(m_neigbours[eForward][0], eForward);
384  m_neigbours[eForward][0]->SetNeigbour(children[0], eBack);
385  m_neigbours[eForward][0]->SetNeigbour(children[1], eBack);
386  m_neigbours[eForward][0]->SetNeigbour(children[2], eBack);
387  m_neigbours[eForward][0]->SetNeigbour(children[3], eBack);
388  }
389  else if (m_neigbours[eForward].size() == 4)
390  {
391  children[0]->SetNeigbour(m_neigbours[eForward][0], eForward); // 4
392  children[1]->SetNeigbour(m_neigbours[eForward][1], eForward); // 5
393  children[2]->SetNeigbour(m_neigbours[eForward][2], eForward); // 6
394  children[3]->SetNeigbour(m_neigbours[eForward][3], eForward); // 7
395  m_neigbours[eForward][0]->SetNeigbour(children[0], eBack);
396  m_neigbours[eForward][1]->SetNeigbour(children[1], eBack);
397  m_neigbours[eForward][2]->SetNeigbour(children[2], eBack);
398  m_neigbours[eForward][3]->SetNeigbour(children[3], eBack);
399  }
400  else if (m_neigbours[eForward].size() != 0)
401  {
402  cout << "!!!!!"
403  << "NOT GOOD"
404  << "!!!!! " << m_neigbours[eForward].size() << endl;
405  }
406 
407  if (m_neigbours[eBack].size() == 1)
408  {
409  children[4]->SetNeigbour(m_neigbours[eBack][0], eBack);
410  children[5]->SetNeigbour(m_neigbours[eBack][0], eBack);
411  children[6]->SetNeigbour(m_neigbours[eBack][0], eBack);
412  children[7]->SetNeigbour(m_neigbours[eBack][0], eBack);
413  m_neigbours[eBack][0]->SetNeigbour(children[4], eForward);
414  m_neigbours[eBack][0]->SetNeigbour(children[5], eForward);
415  m_neigbours[eBack][0]->SetNeigbour(children[6], eForward);
416  m_neigbours[eBack][0]->SetNeigbour(children[7], eForward);
417  }
418  else if (m_neigbours[eBack].size() == 4)
419  {
420  children[4]->SetNeigbour(m_neigbours[eBack][0], eBack); // 0
421  children[5]->SetNeigbour(m_neigbours[eBack][1], eBack); // 1
422  children[6]->SetNeigbour(m_neigbours[eBack][2], eBack); // 2
423  children[7]->SetNeigbour(m_neigbours[eBack][3], eBack); // 3
424  m_neigbours[eBack][0]->SetNeigbour(children[4], eForward);
425  m_neigbours[eBack][1]->SetNeigbour(children[5], eForward);
426  m_neigbours[eBack][2]->SetNeigbour(children[6], eForward);
427  m_neigbours[eBack][3]->SetNeigbour(children[7], eForward);
428  }
429  else if (m_neigbours[eBack].size() != 0)
430  {
431  cout << "!!!!!"
432  << "NOT GOOD"
433  << "!!!!! " << m_neigbours[eBack].size() << endl;
434  }
435 
436  if (m_neigbours[eLeft].size() == 1)
437  {
438  children[0]->SetNeigbour(m_neigbours[eLeft][0], eLeft);
439  children[2]->SetNeigbour(m_neigbours[eLeft][0], eLeft);
440  children[4]->SetNeigbour(m_neigbours[eLeft][0], eLeft);
441  children[6]->SetNeigbour(m_neigbours[eLeft][0], eLeft);
442  m_neigbours[eLeft][0]->SetNeigbour(children[0], eRight);
443  m_neigbours[eLeft][0]->SetNeigbour(children[2], eRight);
444  m_neigbours[eLeft][0]->SetNeigbour(children[4], eRight);
445  m_neigbours[eLeft][0]->SetNeigbour(children[6], eRight);
446  }
447  else if (m_neigbours[eLeft].size() == 4)
448  {
449  children[0]->SetNeigbour(m_neigbours[eLeft][0], eLeft); // 1
450  children[2]->SetNeigbour(m_neigbours[eLeft][1], eLeft); // 3
451  children[4]->SetNeigbour(m_neigbours[eLeft][2], eLeft); // 5
452  children[6]->SetNeigbour(m_neigbours[eLeft][3], eLeft); // 7
453  m_neigbours[eLeft][0]->SetNeigbour(children[0], eRight);
454  m_neigbours[eLeft][1]->SetNeigbour(children[2], eRight);
455  m_neigbours[eLeft][2]->SetNeigbour(children[4], eRight);
456  m_neigbours[eLeft][3]->SetNeigbour(children[6], eRight);
457  }
458  else if (m_neigbours[eLeft].size() != 0)
459  {
460  cout << "!!!!!"
461  << "NOT GOOD"
462  << "!!!!! " << m_neigbours[eLeft].size() << endl;
463  cout << m_neigbours[eLeft].size() << endl;
464  }
465 
466  if (m_neigbours[eRight].size() == 1)
467  {
468  children[1]->SetNeigbour(m_neigbours[eRight][0], eRight);
469  children[3]->SetNeigbour(m_neigbours[eRight][0], eRight);
470  children[5]->SetNeigbour(m_neigbours[eRight][0], eRight);
471  children[7]->SetNeigbour(m_neigbours[eRight][0], eRight);
472  m_neigbours[eRight][0]->SetNeigbour(children[1], eLeft);
473  m_neigbours[eRight][0]->SetNeigbour(children[3], eLeft);
474  m_neigbours[eRight][0]->SetNeigbour(children[5], eLeft);
475  m_neigbours[eRight][0]->SetNeigbour(children[7], eLeft);
476  }
477  else if (m_neigbours[eRight].size() == 4)
478  {
479  children[1]->SetNeigbour(m_neigbours[eRight][0], eRight); // 0
480  children[3]->SetNeigbour(m_neigbours[eRight][1], eRight); // 2
481  children[5]->SetNeigbour(m_neigbours[eRight][2], eRight); // 4
482  children[7]->SetNeigbour(m_neigbours[eRight][3], eRight); // 6
483  m_neigbours[eRight][0]->SetNeigbour(children[1], eLeft);
484  m_neigbours[eRight][1]->SetNeigbour(children[3], eLeft);
485  m_neigbours[eRight][2]->SetNeigbour(children[5], eLeft);
486  m_neigbours[eRight][3]->SetNeigbour(children[7], eLeft);
487  }
488  else if (m_neigbours[eRight].size() != 0)
489  {
490  cout << "!!!!!"
491  << "NOT GOOD"
492  << "!!!!! " << m_neigbours[eRight].size() << endl;
493  }
494 }
495 
497 {
498  vector<OctantSharedPtr> tmp = m_neigbours[f];
499  m_neigbours[f].clear();
500  for (int i = 0; i < tmp.size(); i++)
501  {
502  if (tmp[i]->GetId() != id)
503  {
504  m_neigbours[f].push_back(tmp[i]);
505  }
506  }
507 }
508 
509 bool operator==(OctantSharedPtr const &p1, OctantSharedPtr const &p2)
510 {
511  if (p1->GetId() == p2->GetId())
512  {
513  return true;
514  }
515 
516  return false;
517 }
518 }
519 }
NekDouble GetDelta()
Get value of delta.
Definition: Octant.h:200
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::vector< SPBaseSharedPtr > m_localSPList
curvature sampling point list
Definition: Octant.h:343
OctantLocation m_location
idenify if delta has ben set
Definition: Octant.h:352
void RemoveNeigbour(int id, OctantFace f)
Remove a neigbour from this octants list.
Definition: Octant.cpp:496
bool m_leaf
leaf identifer
Definition: Octant.h:333
STL namespace.
OctantSharedPtr m_parent
parent id
Definition: Octant.h:335
void SetDelta(NekDouble d)
Set the value for delta for this octant.
Definition: Octant.h:191
NekDouble m_hd
half dimension of the octant
Definition: Octant.h:341
NekDouble DX()
Get the octants half dimension.
Definition: Octant.h:141
Octant(int i, OctantSharedPtr p, Array< OneD, OctantFace > dir)
Defualt constructor.
Definition: Octant.cpp:64
bool operator==(ElmtConfig const &c1, ElmtConfig const &c2)
Compares two element config structs.
void Subdivide(OctantSharedPtr p, int &numoct)
Subdivide the octant.
Definition: Octant.cpp:214
int m_numValidPoints
number of valid cp points
Definition: Octant.h:345
int GetId()
Get the Id of the octant.
Definition: Octant.h:125
int NumValidCurvePoint()
Get the number of valid cp points in the octants list.
Definition: Octant.h:183
OctantFace GetReverseFace(OctantFace f)
Definition: Octant.cpp:43
double NekDouble
Array< OneD, NekDouble > m_loc
x,y,z location of the octant
Definition: Octant.h:339
std::shared_ptr< Octant > OctantSharedPtr
Definition: Octant.h:73
OctantFace
enumeration of the 6 faces of a cube/octant
Definition: Octant.h:51
bool m_needToDivide
idenify if division is needed
Definition: Octant.h:350
void SetChildren(Array< OneD, OctantSharedPtr > c)
Set the children of this octant.
Definition: Octant.h:212
std::map< OctantFace, std::vector< OctantSharedPtr > > m_neigbours
list of neighbours
Definition: Octant.h:354
std::pair< bool, NekDouble > m_delta
mesh sizing parameter
Definition: Octant.h:348