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

Constructor & Destructor Documentation

◆ Octant() [1/3]

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

Construct a new Octree::Octant object.

Definition at line 358 of file Octree.cpp.

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

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

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

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

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

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

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

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

◆ GetBounds()

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

Definition at line 132 of file Octree.h.

133 {
134 return m_bounds;
135 }

References m_bounds.

◆ GetCentre()

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

Definition at line 128 of file Octree.h.

129 {
130 return m_centre;
131 }

References m_centre.

Referenced by Octant().

◆ GetChildren()

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

Definition at line 140 of file Octree.h.

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

References m_children.

◆ GetDelta()

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

Definition at line 116 of file Octree.h.

117 {
118 return m_delta;
119 }

References m_delta.

Referenced by Octant().

◆ GetDepth()

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

Definition at line 112 of file Octree.h.

113 {
114 return m_depth;
115 }

References m_depth.

Referenced by Octant().

◆ GetID()

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

Definition at line 120 of file Octree.h.

121 {
122 return m_id;
123 }

References m_id.

◆ GetIndices()

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

Definition at line 136 of file Octree.h.

137 {
138 return m_pointInd;
139 }

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

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

◆ GetLoc()

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

Definition at line 108 of file Octree.h.

109 {
110 return m_loc;
111 }

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

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

◆ GetNeighbours()

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

Definition at line 144 of file Octree.h.

145 {
146 return m_neighbours;
147 }

References m_neighbours.

◆ GetNpoints()

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

Definition at line 104 of file Octree.h.

105 {
106 return m_nPts;
107 }

References m_nPts.

◆ IsLeaf()

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

Definition at line 124 of file Octree.h.

125 {
126 return m_isLeaf;
127 }

References m_isLeaf.

◆ SetID()

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

Definition at line 149 of file Octree.h.

150 {
151 m_id = id;
152 }

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

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

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

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

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 178 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 176 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 185 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 174 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 170 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 172 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 182 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 168 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 187 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 166 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 180 of file Octree.h.

Referenced by GetIndices().