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 83 of file Octree.h.

Constructor & Destructor Documentation

◆ Octant() [1/3]

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

Construct a new Octree::Octant object.

Definition at line 357 of file Octree.cpp.

357  : m_nPts(-1), m_loc(-1), m_depth(-1), m_id(-1),
358  m_delta(-1), m_centre(3), m_bounds(6), m_isLeaf(true)
359 {
360 }
Array< OneD, NekDouble > m_centre
Coordinates of the centre of the octant.
Definition: Octree.h:130
int m_depth
Depth in octree (root is 1)
Definition: Octree.h:124
double m_delta
Length of the octant side.
Definition: Octree.h:128
int m_loc
Position in the father octant (1-8)
Definition: Octree.h:122
int m_nPts
Number of points in the octant.
Definition: Octree.h:120
Array< OneD, NekDouble > m_bounds
Min/max coordinates of the octant (x, y, z)
Definition: Octree.h:132
bool m_isLeaf
True for a leaf octant, false otherwise.
Definition: Octree.h:136
int m_id
ID of the octant (index in 'm_nodes' vector)
Definition: Octree.h:126

◆ 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 370 of file Octree.cpp.

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

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

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 525 of file Octree.cpp.

527 {
528  for (const OctantSharedPtr &neighbour : neighbours)
529  {
530  bool equal = false;
531  for (const OctantWeakPtr &neigh: m_neighbours)
532  {
533  if (neigh.lock()->GetID() == neighbour->GetID())
534  {
535  equal = true;
536  break;
537  }
538  }
539  if (!equal)
540  {
541  m_neighbours.push_back(neighbour);
542  }
543  }
544 }
std::vector< OctantWeakPtr > m_neighbours
Vector of pointers to the neighbouring octants.
Definition: Octree.h:141
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 553 of file Octree.cpp.

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

◆ GetBounds()

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

Definition at line 101 of file Octree.h.

101 { return m_bounds; }

References m_bounds.

◆ GetCentre()

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

Definition at line 100 of file Octree.h.

100 { return m_centre; }

References m_centre.

Referenced by Octant().

◆ GetChildren()

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

Definition at line 103 of file Octree.h.

103 { return m_children; }
Array< OneD, OctantSharedPtr > m_children
Vector of pointers to the children octants.
Definition: Octree.h:139

References m_children.

◆ GetDelta()

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

Definition at line 97 of file Octree.h.

97 { return m_delta; }

References m_delta.

Referenced by Octant().

◆ GetDepth()

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

Definition at line 96 of file Octree.h.

96 { return m_depth; }

References m_depth.

Referenced by Octant().

◆ GetID()

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

Definition at line 98 of file Octree.h.

98 { return m_id; }

References m_id.

◆ GetIndices()

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

Definition at line 102 of file Octree.h.

102 { return m_pointInd; }

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 491 of file Octree.cpp.

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

◆ GetLoc()

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

Definition at line 95 of file Octree.h.

95 { return m_loc; }

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 633 of file Octree.cpp.

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

◆ GetNeighbours()

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

Definition at line 104 of file Octree.h.

104 { return m_neighbours; }

References m_neighbours.

◆ GetNpoints()

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

Definition at line 94 of file Octree.h.

94 { return m_nPts; }

References m_nPts.

◆ IsLeaf()

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

Definition at line 99 of file Octree.h.

99 { return m_isLeaf; }

References m_isLeaf.

◆ SetID()

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

Definition at line 106 of file Octree.h.

106 { m_id = id; }

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 511 of file Octree.cpp.

512 {
513  for (int i : indices)
514  {
515  m_pointInd.push_back(i);
516  }
517  m_nPts = indices.size();
518 }

◆ 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 590 of file Octree.cpp.

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

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 132 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 130 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 139 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 128 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 124 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 126 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 136 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 122 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 141 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 120 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 134 of file Octree.h.

Referenced by GetIndices().