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().