Nektar++
Public Member Functions | Private Attributes | List of all members
Nektar::FieldUtils::Octree::Octant Class Reference
Inheritance diagram for Nektar::FieldUtils::Octree::Octant:
[legend]

Public Member Functions

 Octant ()
 Construct a new Octree::Octant object. More...
 
 Octant (int loc, int depth, int id, const Array< OneD, NekDouble > &bounds)
 Construct a new Octree::Octant object. More...
 
 Octant (int loc, Octant &parent)
 Construct a new Octree::Octant object. More...
 
int GetNpoints () const
 
int GetLoc () const
 
int GetDepth () const
 
double GetDelta () const
 
int GetID () const
 
bool IsLeaf () const
 
Array< OneD, NekDouble > & GetCentre ()
 
Array< OneD, NekDouble > & GetBounds ()
 
std::vector< int > & GetIndices ()
 
Array< OneD, OctantSharedPtr > & GetChildren ()
 
std::vector< OctantWeakPtr > & GetNeighbours ()
 
void SetID (int id)
 
void GetLeaves (std::vector< OctantSharedPtr > &leaves)
 Updates 'leaves' so that it contains all the leaf nodes belonging to the octant. More...
 
void SetIndices (const std::vector< int > &indices)
 Sets the values of 'm_pointInd' to those in 'indices'. More...
 
void AddNeighbours (const std::vector< OctantSharedPtr > &neighbours)
 Adds to 'm_neighbours' the octants that are not already in the list. More...
 
void AddPoints (const Array< OneD, Array< OneD, NekDouble >> &pts, const std::vector< int > &indices)
 Adds to 'm_pointInd' the IDs of the points in 'pts' that fall inside the octant. More...
 
void Subdivide (int maxPts, const Array< OneD, Array< OneD, NekDouble >> &pts, std::vector< OctantSharedPtr > &nodes)
 Recursively divides the octant into 8 children and fills the leaf nodes with their corresponding points. Does NOT add neighbours. More...
 
int GetLocInNode (const Array< OneD, NekDouble > &coords)
 Returns the position inside an octant in the range (1-8). The name convention is as follows: let \(\Delta\) be a value between 0 and the length of the side of the father octant, and \(x_c,y_c,z_c\) be the coordinates of the centre of the father node. Then, position 1 corresponds to \(x=x_c-\Delta\), \(y=y_c-\Delta\) and \(y=y_c-\Delta\). The next positions are obtained by rotating counter-clockwise around the Z axis and then, making the same rotation for \(z=z_c+\Delta\). More...
 

Private Attributes

int m_nPts
 Number of points in the octant. More...
 
int m_loc
 Position in the father octant (1-8) More...
 
int m_depth
 Depth in octree (root is 1) More...
 
int m_id
 ID of the octant (index in 'm_nodes' vector) More...
 
double m_delta
 Length of the octant side. More...
 
Array< OneD, NekDoublem_centre
 Coordinates of the centre of the octant. More...
 
Array< OneD, NekDoublem_bounds
 Min/max coordinates of the octant (x, y, z) More...
 
std::vector< int > m_pointInd
 Indices of the points comprised by the octant. More...
 
bool m_isLeaf
 True for a leaf octant, false otherwise. More...
 
Array< OneD, OctantSharedPtrm_children
 Vector of pointers to the children octants. More...
 
std::vector< OctantWeakPtrm_neighbours
 Vector of pointers to the neighbouring octants. More...
 

Detailed Description

Definition at line 95 of file Octree.h.

Constructor & Destructor Documentation

◆ Octant() [1/3]

Nektar::FieldUtils::Octree::Octant::Octant ( )

Construct a new Octree::Octant object.

Definition at line 360 of file Octree.cpp.

361  : m_nPts(-1), m_loc(-1), m_depth(-1), m_id(-1), m_delta(-1), m_centre(3),
362  m_bounds(6), m_isLeaf(true)
363 {
364 }
Array< OneD, NekDouble > m_centre
Coordinates of the centre of the octant.
Definition: Octree.h:178
int m_depth
Depth in octree (root is 1)
Definition: Octree.h:172
double m_delta
Length of the octant side.
Definition: Octree.h:176
int m_loc
Position in the father octant (1-8)
Definition: Octree.h:170
int m_nPts
Number of points in the octant.
Definition: Octree.h:168
Array< OneD, NekDouble > m_bounds
Min/max coordinates of the octant (x, y, z)
Definition: Octree.h:180
bool m_isLeaf
True for a leaf octant, false otherwise.
Definition: Octree.h:184
int m_id
ID of the octant (index in 'm_nodes' vector)
Definition: Octree.h:174

◆ Octant() [2/3]

Nektar::FieldUtils::Octree::Octant::Octant ( int  loc,
int  depth,
int  id,
const Array< OneD, NekDouble > &  bounds 
)

Construct a new Octree::Octant object.

Parameters
loc
depth
id
bounds

Definition at line 374 of file Octree.cpp.

376  : m_nPts(0), m_loc(loc), m_depth(depth), m_id(id), m_isLeaf(true)
377 {
378  // Check the size of 'bounds'
379  if (bounds.size() != 6)
380  {
381  throw std::out_of_range("Size of bounds must be 6.");
382  }
383 
384  // If all deltas are not equal, use the largest ones
385  NekDouble deltaX = bounds[1] - bounds[0];
386  NekDouble deltaY = bounds[3] - bounds[2];
387  NekDouble deltaZ = bounds[5] - bounds[4];
388  if (deltaX != deltaY || deltaY != deltaZ)
389  {
390  m_delta = (deltaX > deltaY) ? deltaX : deltaY;
391  m_delta = (m_delta > deltaZ) ? m_delta : deltaZ;
392  }
393  else
394  {
395  m_delta = deltaX;
396  }
397 
398  // Fill in the rest of the data
399  m_centre = Array<OneD, NekDouble>(3);
400  m_bounds = Array<OneD, NekDouble>(6);
401  for (int i = 0; i < 3; ++i)
402  {
403  m_centre[i] = (bounds[2 * i + 1] + bounds[2 * i]) / 2.0;
404  m_bounds[2 * i] = m_centre[i] - m_delta / 2.0;
405  m_bounds[2 * i + 1] = m_centre[i] + m_delta / 2.0;
406  }
407 }
double NekDouble

References m_bounds, m_centre, and m_delta.

◆ Octant() [3/3]

Nektar::FieldUtils::Octree::Octant::Octant ( int  loc,
Octant parent 
)

Construct a new Octree::Octant object.

Parameters
loc
parent

Definition at line 415 of file Octree.cpp.

416  : m_nPts(0), m_loc(loc), m_id(-1), m_isLeaf(true)
417 {
418  // Set depth
419  m_depth = parent.GetDepth() + 1;
420 
421  // Set delta
422  m_delta = parent.GetDelta() / 2.0;
423 
424  // Set centre
425  NekDouble centreDX;
426  NekDouble centreDY;
427  NekDouble centreDZ;
428  switch (loc)
429  {
430  case 1: // x-, y-, z-
431  centreDX = -m_delta / 2.0;
432  centreDY = -m_delta / 2.0;
433  centreDZ = -m_delta / 2.0;
434  break;
435  case 2: // x+, y-, z-
436  centreDX = m_delta / 2.0;
437  centreDY = -m_delta / 2.0;
438  centreDZ = -m_delta / 2.0;
439  break;
440  case 3: // x+, y+, z-
441  centreDX = m_delta / 2.0;
442  centreDY = m_delta / 2.0;
443  centreDZ = -m_delta / 2.0;
444  break;
445  case 4: // x-, y+, z-
446  centreDX = -m_delta / 2.0;
447  centreDY = m_delta / 2.0;
448  centreDZ = -m_delta / 2.0;
449  break;
450  case 5: // x-, y-, z+
451  centreDX = -m_delta / 2.0;
452  centreDY = -m_delta / 2.0;
453  centreDZ = m_delta / 2.0;
454  break;
455  case 6: // x+, y-, z+
456  centreDX = m_delta / 2.0;
457  centreDY = -m_delta / 2.0;
458  centreDZ = m_delta / 2.0;
459  break;
460  case 7: // x+, y+, z+
461  centreDX = m_delta / 2.0;
462  centreDY = m_delta / 2.0;
463  centreDZ = m_delta / 2.0;
464  break;
465  case 8: // x-, y+, z+
466  centreDX = -m_delta / 2.0;
467  centreDY = m_delta / 2.0;
468  centreDZ = m_delta / 2.0;
469  break;
470  default:
471  throw std::out_of_range("Loc must be in the range (1,8).");
472  }
473  Array<OneD, NekDouble> pCentre = parent.GetCentre();
474  m_centre = Array<OneD, NekDouble>(3);
475  m_centre[0] = pCentre[0] + centreDX;
476  m_centre[1] = pCentre[1] + centreDY;
477  m_centre[2] = pCentre[2] + centreDZ;
478 
479  // Set bounds
480  m_bounds = Array<OneD, NekDouble>(6);
481  for (int i = 0; i < 3; ++i)
482  {
483  m_bounds[2 * i] = m_centre[i] - m_delta / 2.0;
484  m_bounds[2 * i + 1] = m_centre[i] + m_delta / 2.0;
485  }
486 }

References GetCentre(), GetDelta(), GetDepth(), CG_Iterations::loc, m_bounds, m_centre, m_delta, and m_depth.

Member Function Documentation

◆ AddNeighbours()

void Nektar::FieldUtils::Octree::Octant::AddNeighbours ( const std::vector< OctantSharedPtr > &  neighbours)

Adds to 'm_neighbours' the octants that are not already in the list.

Parameters
neighbours

Definition at line 528 of file Octree.cpp.

530 {
531  for (const OctantSharedPtr &neighbour : neighbours)
532  {
533  bool equal = false;
534  for (const OctantWeakPtr &neigh : m_neighbours)
535  {
536  if (neigh.lock()->GetID() == neighbour->GetID())
537  {
538  equal = true;
539  break;
540  }
541  }
542  if (!equal)
543  {
544  m_neighbours.push_back(neighbour);
545  }
546  }
547 }
std::vector< OctantWeakPtr > m_neighbours
Vector of pointers to the neighbouring octants.
Definition: Octree.h:189
std::shared_ptr< Octant > OctantSharedPtr
Definition: Octree.h:48
std::weak_ptr< Octant > OctantWeakPtr
Definition: Octree.h:49

◆ AddPoints()

void Nektar::FieldUtils::Octree::Octant::AddPoints ( const Array< OneD, Array< OneD, NekDouble >> &  pts,
const std::vector< int > &  indices 
)

Adds to 'm_pointInd' the IDs of the points in 'pts' that fall inside the octant.

Parameters
pts
indices

Definition at line 556 of file Octree.cpp.

558 {
559  for (int i : indices)
560  {
561  // Check if the point is inside the node
562  Array<OneD, NekDouble> pt = pts[i];
563  if ((pt[0] < m_bounds[0]) || (pt[0] > m_bounds[1]))
564  {
565  continue;
566  }
567  if ((pt[1] < m_bounds[2]) || (pt[1] > m_bounds[3]))
568  {
569  continue;
570  }
571  if ((pt[2] < m_bounds[4]) || (pt[2] > m_bounds[5]))
572  {
573  continue;
574  }
575 
576  // If so, add it to the list
577  m_nPts++;
578  m_pointInd.push_back(i);
579 
580  // Flag it as a leaf node
581  m_isLeaf = true;
582  }
583 }
std::vector< int > m_pointInd
Indices of the points comprised by the octant.
Definition: Octree.h:182

◆ GetBounds()

Array<OneD, NekDouble>& Nektar::FieldUtils::Octree::Octant::GetBounds ( )
inline

Definition at line 134 of file Octree.h.

135  {
136  return m_bounds;
137  }

References m_bounds.

◆ GetCentre()

Array<OneD, NekDouble>& Nektar::FieldUtils::Octree::Octant::GetCentre ( )
inline

Definition at line 130 of file Octree.h.

131  {
132  return m_centre;
133  }

References m_centre.

Referenced by Octant().

◆ GetChildren()

Array<OneD, OctantSharedPtr>& Nektar::FieldUtils::Octree::Octant::GetChildren ( )
inline

Definition at line 142 of file Octree.h.

143  {
144  return m_children;
145  }
Array< OneD, OctantSharedPtr > m_children
Vector of pointers to the children octants.
Definition: Octree.h:187

References m_children.

◆ GetDelta()

double Nektar::FieldUtils::Octree::Octant::GetDelta ( ) const
inline

Definition at line 118 of file Octree.h.

119  {
120  return m_delta;
121  }

References m_delta.

Referenced by Octant().

◆ GetDepth()

int Nektar::FieldUtils::Octree::Octant::GetDepth ( ) const
inline

Definition at line 114 of file Octree.h.

115  {
116  return m_depth;
117  }

References m_depth.

Referenced by Octant().

◆ GetID()

int Nektar::FieldUtils::Octree::Octant::GetID ( ) const
inline

Definition at line 122 of file Octree.h.

123  {
124  return m_id;
125  }

References m_id.

◆ GetIndices()

std::vector<int>& Nektar::FieldUtils::Octree::Octant::GetIndices ( )
inline

Definition at line 138 of file Octree.h.

139  {
140  return m_pointInd;
141  }

References m_pointInd.

◆ GetLeaves()

void Nektar::FieldUtils::Octree::Octant::GetLeaves ( std::vector< OctantSharedPtr > &  leaves)

Updates 'leaves' so that it contains all the leaf nodes belonging to the octant.

Parameters
leaves

Definition at line 494 of file Octree.cpp.

495 {
496  if (m_isLeaf)
497  {
498  leaves.push_back(shared_from_this());
499  }
500  else
501  {
502  for (OctantSharedPtr child : m_children)
503  {
504  child->GetLeaves(leaves);
505  }
506  }
507 }

◆ GetLoc()

int Nektar::FieldUtils::Octree::Octant::GetLoc ( ) const
inline

Definition at line 110 of file Octree.h.

111  {
112  return m_loc;
113  }

References m_loc.

◆ GetLocInNode()

int Nektar::FieldUtils::Octree::Octant::GetLocInNode ( const Array< OneD, NekDouble > &  coords)

Returns the position inside an octant in the range (1-8). The name convention is as follows: let \(\Delta\) be a value between 0 and the length of the side of the father octant, and \(x_c,y_c,z_c\) be the coordinates of the centre of the father node. Then, position 1 corresponds to \(x=x_c-\Delta\), \(y=y_c-\Delta\) and \(y=y_c-\Delta\). The next positions are obtained by rotating counter-clockwise around the Z axis and then, making the same rotation for \(z=z_c+\Delta\).

Parameters
coords
Returns
int

Definition at line 636 of file Octree.cpp.

637 {
638  // Different positions as bits in 'posByte'
639  // MSB <==> LSB
640  unsigned char posByte;
641 
642  if (coords[0] <= m_centre[0]) // x-
643  {
644  posByte = 153; // 0b10011001;
645  }
646  else // x+
647  {
648  posByte = 102; // 0b01100110;
649  }
650  if (coords[1] <= m_centre[1]) // y-
651  {
652  posByte &= 51; // 0b00110011;
653  }
654  else // y+
655  {
656  posByte &= 204; // 0b11001100;
657  }
658  if (coords[2] <= m_centre[2]) // z-
659  {
660  posByte &= 15; // 0b00001111;
661  }
662  else // z+
663  {
664  posByte &= 240; // 0b11110000;
665  }
666 
667  // Transform into a position in the range (1,8)
668  int position = 1;
669  while (posByte > 1)
670  {
671  posByte = posByte >> 1;
672  position++;
673  }
674 
675  return position;
676 }

◆ GetNeighbours()

std::vector<OctantWeakPtr>& Nektar::FieldUtils::Octree::Octant::GetNeighbours ( )
inline

Definition at line 146 of file Octree.h.

147  {
148  return m_neighbours;
149  }

References m_neighbours.

◆ GetNpoints()

int Nektar::FieldUtils::Octree::Octant::GetNpoints ( void  ) const
inline

Definition at line 106 of file Octree.h.

107  {
108  return m_nPts;
109  }

References m_nPts.

◆ IsLeaf()

bool Nektar::FieldUtils::Octree::Octant::IsLeaf ( ) const
inline

Definition at line 126 of file Octree.h.

127  {
128  return m_isLeaf;
129  }

References m_isLeaf.

◆ SetID()

void Nektar::FieldUtils::Octree::Octant::SetID ( int  id)
inline

Definition at line 151 of file Octree.h.

152  {
153  m_id = id;
154  }

References m_id.

◆ SetIndices()

void Nektar::FieldUtils::Octree::Octant::SetIndices ( const std::vector< int > &  indices)

Sets the values of 'm_pointInd' to those in 'indices'.

Parameters
indices

Definition at line 514 of file Octree.cpp.

515 {
516  for (int i : indices)
517  {
518  m_pointInd.push_back(i);
519  }
520  m_nPts = indices.size();
521 }

◆ Subdivide()

void Nektar::FieldUtils::Octree::Octant::Subdivide ( int  maxPts,
const Array< OneD, Array< OneD, NekDouble >> &  pts,
std::vector< OctantSharedPtr > &  nodes 
)

Recursively divides the octant into 8 children and fills the leaf nodes with their corresponding points. Does NOT add neighbours.

Parameters
maxPts
pts
nodes

Definition at line 593 of file Octree.cpp.

596 {
597  // For a non-leaf node
598  if (m_nPts > maxPts)
599  {
600  // Create and fill children RECURSIVELY
601  m_children = Array<OneD, OctantSharedPtr>(8);
602  for (int i = 0; i < 8; ++i)
603  {
604  OctantSharedPtr newChild =
605  std::make_shared<Octant>(i + 1, *shared_from_this());
606  newChild->AddPoints(pts, m_pointInd);
607  newChild->SetID(nodes.size()); // ID's start from 0
608 
609  // Add it to the list
610  m_children[i] = newChild;
611  nodes.push_back(newChild);
612 
613  // Keep dividing
614  newChild->Subdivide(maxPts, pts, nodes); // Recursion
615  }
616 
617  // Not a leaf node anymore
618  m_pointInd.clear();
619  m_nPts = 0;
620  m_isLeaf = false;
621  }
622 }

Member Data Documentation

◆ m_bounds

Array<OneD, NekDouble> Nektar::FieldUtils::Octree::Octant::m_bounds
private

Min/max coordinates of the octant (x, y, z)

Definition at line 180 of file Octree.h.

Referenced by GetBounds(), and Octant().

◆ m_centre

Array<OneD, NekDouble> Nektar::FieldUtils::Octree::Octant::m_centre
private

Coordinates of the centre of the octant.

Definition at line 178 of file Octree.h.

Referenced by GetCentre(), and Octant().

◆ m_children

Array<OneD, OctantSharedPtr> Nektar::FieldUtils::Octree::Octant::m_children
private

Vector of pointers to the children octants.

Definition at line 187 of file Octree.h.

Referenced by GetChildren().

◆ m_delta

double Nektar::FieldUtils::Octree::Octant::m_delta
private

Length of the octant side.

Definition at line 176 of file Octree.h.

Referenced by GetDelta(), and Octant().

◆ m_depth

int Nektar::FieldUtils::Octree::Octant::m_depth
private

Depth in octree (root is 1)

Definition at line 172 of file Octree.h.

Referenced by GetDepth(), and Octant().

◆ m_id

int Nektar::FieldUtils::Octree::Octant::m_id
private

ID of the octant (index in 'm_nodes' vector)

Definition at line 174 of file Octree.h.

Referenced by GetID(), and SetID().

◆ m_isLeaf

bool Nektar::FieldUtils::Octree::Octant::m_isLeaf
private

True for a leaf octant, false otherwise.

Definition at line 184 of file Octree.h.

Referenced by IsLeaf().

◆ m_loc

int Nektar::FieldUtils::Octree::Octant::m_loc
private

Position in the father octant (1-8)

Definition at line 170 of file Octree.h.

Referenced by GetLoc().

◆ m_neighbours

std::vector<OctantWeakPtr> Nektar::FieldUtils::Octree::Octant::m_neighbours
private

Vector of pointers to the neighbouring octants.

Definition at line 189 of file Octree.h.

Referenced by GetNeighbours().

◆ m_nPts

int Nektar::FieldUtils::Octree::Octant::m_nPts
private

Number of points in the octant.

Definition at line 168 of file Octree.h.

Referenced by GetNpoints().

◆ m_pointInd

std::vector<int> Nektar::FieldUtils::Octree::Octant::m_pointInd
private

Indices of the points comprised by the octant.

Definition at line 182 of file Octree.h.

Referenced by GetIndices().