Nektar++
Classes | Public Member Functions | Private Types | Private Member Functions | Private Attributes | List of all members
Nektar::FieldUtils::Octree Class Reference

#include <Octree.h>

Classes

class  Octant
 

Public Member Functions

 Octree ()
 Construct a new octree object. More...
 
 Octree (const Array< OneD, Array< OneD, NekDouble > > &pts, int maxPts, const Array< OneD, NekDouble > &bounds)
 Construct a new octree object. More...
 
 Octree (const Array< OneD, Array< OneD, NekDouble > > &pts, int maxPts)
 Construct a new octree object. More...
 
int QueryNode (const Array< OneD, NekDouble > &coords, int depth=std::numeric_limits< int >::max())
 Given the coordinates 'coords' of a point, returns the leaf octant that contains it. If 'depth' is specified, returs the node that contains the point such that its depth is lower or equal to the one indicated. If the point lies outside the tree, it returns -1. More...
 
int QueryClosest (const Array< OneD, Array< OneD, NekDouble > > &pts, const Array< OneD, NekDouble > &coords, double &distance, int pointInd=-1)
 Finds the ID of the closest point in 'pts' to the one specified by 'coords'. It also returns the distance between both points in 'distance'. More...
 
std::vector< int > QueryPoints (int nodeID)
 Returns the indices of the points of the mesh contained in the tree. More...
 
std::vector< int > QueryNeighbours (int nodeID)
 Returns the IDs of the octants that surround the queried node. First, it finds the neighbouring nodes with the same or lower depth and, if they are not leaf nodes, return all the leaf octants contained in them. This means that, for octants of depth 2, this function returns all the leaf nodes in the tree except those lying inside the queried octant. More...
 
int QueryNpoints (int nodeID)
 
int QueryLocation (int nodeID)
 
int QueryDepth (int nodeID)
 
int QueryDelta (int nodeID)
 
void GetStats (int &maxPts, int &nPts, int &nNodes, int &nLeaves, int &depth)
 Returns some characteristic values of the tree. More...
 

Private Types

using OctantSharedPtr = std::shared_ptr< Octant >
 
using OctantWeakPtr = std::weak_ptr< Octant >
 

Private Member Functions

void AdvanceToStats (int nodeID)
 Goes through all the nodes of the octree counting the number of octants and the maximum depth reached. More...
 
void SetNeighbours (int nodeID)
 Once the nodes of the octree are created, sets their neighbours as explained in 'Octree::QueryNeighbours'. More...
 

Private Attributes

int m_maxPts
 Max points allowed in each octant. More...
 
int m_nMshPts
 Number of points in the mesh. More...
 
int m_nNodes
 Number of octants in the tree. More...
 
int m_nLeaves
 Number of leaf nodes in the tree. More...
 
int m_maxDepth
 Maximum depth of the tree. More...
 
OctantSharedPtr m_root
 First node of the tree, linked to the rest. More...
 
std::vector< OctantSharedPtrm_nodes
 Vector of pointers to every octant in the tree. More...
 

Detailed Description

Definition at line 45 of file Octree.h.

Member Typedef Documentation

◆ OctantSharedPtr

using Nektar::FieldUtils::Octree::OctantSharedPtr = std::shared_ptr<Octant>
private

Definition at line 48 of file Octree.h.

◆ OctantWeakPtr

using Nektar::FieldUtils::Octree::OctantWeakPtr = std::weak_ptr<Octant>
private

Definition at line 49 of file Octree.h.

Constructor & Destructor Documentation

◆ Octree() [1/3]

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

Construct a new octree object.

Definition at line 48 of file Octree.cpp.

48  : m_maxPts(0), m_nMshPts(0), m_nNodes(0), m_nLeaves(0),
49  m_maxDepth(0), m_root(nullptr)
50 {
51 }
OctantSharedPtr m_root
First node of the tree, linked to the rest.
Definition: Octree.h:156
int m_nNodes
Number of octants in the tree.
Definition: Octree.h:149
int m_nLeaves
Number of leaf nodes in the tree.
Definition: Octree.h:151
int m_maxPts
Max points allowed in each octant.
Definition: Octree.h:145
int m_maxDepth
Maximum depth of the tree.
Definition: Octree.h:153
int m_nMshPts
Number of points in the mesh.
Definition: Octree.h:147

Referenced by Octree().

◆ Octree() [2/3]

Nektar::FieldUtils::Octree::Octree ( const Array< OneD, Array< OneD, NekDouble > > &  pts,
int  maxPts,
const Array< OneD, NekDouble > &  bounds 
)

Construct a new octree object.

Parameters
pts
maxPts
bounds

Definition at line 60 of file Octree.cpp.

62 {
63  // Set some values
64  m_maxPts = maxPts;
65  m_nMshPts = pts.size();
66 
67  // Create first (root) node
68  std::vector<int> indices(m_nMshPts);
69  for (int i = 0; i < m_nMshPts; ++i)
70  {
71  indices[i] = i;
72  }
73  m_root = std::make_shared<Octant>(0, 1, 0, bounds);
74  m_root->SetIndices(indices);
75  m_nodes.push_back(m_root);
76 
77  // Create the tree
78  m_root->Subdivide(m_maxPts, pts, m_nodes);
79 
80  // Get some data after the tree is computed
81  m_maxDepth = 0;
82  AdvanceToStats(m_root->GetID());
83  m_nNodes = m_nodes.size();
84 
85  // Set the pointers to the neighbouring nodes
86  SetNeighbours(m_root->GetID());
87 }
void SetNeighbours(int nodeID)
Once the nodes of the octree are created, sets their neighbours as explained in 'Octree::QueryNeighbo...
Definition: Octree.cpp:312
void AdvanceToStats(int nodeID)
Goes through all the nodes of the octree counting the number of octants and the maximum depth reached...
Definition: Octree.cpp:286
std::vector< OctantSharedPtr > m_nodes
Vector of pointers to every octant in the tree.
Definition: Octree.h:158

References AdvanceToStats(), m_maxDepth, m_maxPts, m_nMshPts, m_nNodes, m_nodes, m_root, and SetNeighbours().

◆ Octree() [3/3]

Nektar::FieldUtils::Octree::Octree ( const Array< OneD, Array< OneD, NekDouble > > &  pts,
int  maxPts 
)

Construct a new octree object.

Parameters
pts
maxPts

Definition at line 95 of file Octree.cpp.

96 {
97  // Small margin to avoid rounding errors
98  NekDouble margin = 1e-10;
99 
100  // Find coordinates of the bounding box
101  Array<OneD, NekDouble> bounds(6);
102  bounds[0] = pts[0][0];
103  bounds[1] = pts[0][0];
104  bounds[2] = pts[0][1];
105  bounds[3] = pts[0][1];
106  bounds[4] = pts[0][2];
107  bounds[5] = pts[0][2];
108  for (int i = 1; i < m_nMshPts; ++i)
109  {
110  bounds[0] = (bounds[0] < pts[i][0]) ? bounds[0] : pts[i][0];
111  bounds[1] = (bounds[1] > pts[i][0]) ? bounds[1] : pts[i][0];
112  bounds[2] = (bounds[2] < pts[i][1]) ? bounds[2] : pts[i][1];
113  bounds[3] = (bounds[3] > pts[i][1]) ? bounds[3] : pts[i][1];
114  bounds[4] = (bounds[4] < pts[i][2]) ? bounds[4] : pts[i][2];
115  bounds[5] = (bounds[5] > pts[i][2]) ? bounds[5] : pts[i][2];
116  }
117 
118  // Add the margin
119  for (int i = 0; i < 6; ++i)
120  {
121  bounds[i] -= pow(-1,i) * margin;
122  }
123 
124  // Call the octree constructor
125  Octree(pts, maxPts, bounds);
126 }
Octree()
Construct a new octree object.
Definition: Octree.cpp:48
double NekDouble

References m_nMshPts, and Octree().

Member Function Documentation

◆ AdvanceToStats()

void Nektar::FieldUtils::Octree::AdvanceToStats ( int  nodeID)
private

Goes through all the nodes of the octree counting the number of octants and the maximum depth reached.

Parameters
nodeID

Definition at line 286 of file Octree.cpp.

287 {
288  // Update stats if we reached the end of the branch
289  if (m_nodes[nodeID]->IsLeaf())
290  {
291  m_nLeaves++;
292  m_maxDepth = (m_maxDepth > m_nodes[nodeID]->GetDepth()) ? m_maxDepth :
293  m_nodes[nodeID]->GetDepth();
294  }
295  // In any other case, dig into the tree
296  else
297  {
298  Array<OneD, OctantSharedPtr> children = m_nodes[nodeID]->GetChildren();
299  for (OctantSharedPtr child : children)
300  {
301  AdvanceToStats(child->GetID());
302  }
303  }
304 }
std::shared_ptr< Octant > OctantSharedPtr
Definition: Octree.h:48

References m_maxDepth, m_nLeaves, and m_nodes.

Referenced by Octree().

◆ GetStats()

void Nektar::FieldUtils::Octree::GetStats ( int &  maxPts,
int &  nPts,
int &  nNodes,
int &  nLeaves,
int &  depth 
)

Returns some characteristic values of the tree.

Parameters
maxPts
nPts
nNodes
nLeaves
depth

Definition at line 270 of file Octree.cpp.

272 {
273  maxPts = m_maxPts;
274  nPts = m_nMshPts;
275  nNodes = m_nNodes;
276  nLeaves = m_nLeaves;
277  depth = m_maxDepth;
278 }

References m_maxDepth, m_maxPts, m_nLeaves, m_nMshPts, and m_nNodes.

◆ QueryClosest()

int Nektar::FieldUtils::Octree::QueryClosest ( const Array< OneD, Array< OneD, NekDouble > > &  pts,
const Array< OneD, NekDouble > &  coords,
double &  distance,
int  pointInd = -1 
)

Finds the ID of the closest point in 'pts' to the one specified by 'coords'. It also returns the distance between both points in 'distance'.

Parameters
pts
coords
distance
pointInd
Returns
int

Definition at line 177 of file Octree.cpp.

180 {
181  int index = -1;
182  distance = std::numeric_limits<NekDouble>::max();
183 
184  if (coords.size())
185  {
186  // Find the corresponding node to 'coords'
187  int nodeInd;
188  if (pointInd > 0)
189  {
190  nodeInd = pointInd;
191  }
192  else
193  {
194  nodeInd = QueryNode(coords);
195  }
196 
197  // List the indices of all the candidate points
198  std::vector<int> indices(m_nodes[nodeInd]->GetIndices());
199  for (OctantWeakPtr neigh : m_nodes[nodeInd]->GetNeighbours())
200  {
201  for (int i : neigh.lock()->GetIndices())
202  {
203  indices.push_back(i);
204  }
205  }
206 
207  // Check the distances with all the nodes
208  for (int i : indices)
209  {
210  NekDouble sub = pts[i][0]-coords[0];
211  NekDouble tmpDistance = sub * sub;
212  for (int j = 1; j < 3; ++j)
213  {
214  sub = pts[i][j]-coords[j];
215  tmpDistance += sub * sub;
216  }
217  tmpDistance = std::sqrt(tmpDistance);
218 
219  if (distance > tmpDistance)
220  {
221  distance = tmpDistance;
222  index = i;
223  }
224  }
225  }
226 
227  return index;
228 }
std::weak_ptr< Octant > OctantWeakPtr
Definition: Octree.h:49
int QueryNode(const Array< OneD, NekDouble > &coords, int depth=std::numeric_limits< int >::max())
Given the coordinates 'coords' of a point, returns the leaf octant that contains it....
Definition: Octree.cpp:138
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:267

References m_nodes, QueryNode(), and tinysimd::sqrt().

◆ QueryDelta()

int Nektar::FieldUtils::Octree::QueryDelta ( int  nodeID)
inline

Definition at line 76 of file Octree.h.

76 { return m_nodes[nodeID]->GetDelta(); }

References m_nodes.

◆ QueryDepth()

int Nektar::FieldUtils::Octree::QueryDepth ( int  nodeID)
inline

Definition at line 75 of file Octree.h.

75 { return m_nodes[nodeID]->GetDepth(); }

References m_nodes.

Referenced by Nektar::FieldUtils::ProcessPhiFromFile::FindShortestDist().

◆ QueryLocation()

int Nektar::FieldUtils::Octree::QueryLocation ( int  nodeID)
inline

Definition at line 74 of file Octree.h.

74 { return m_nodes[nodeID]->GetLoc(); }

References m_nodes.

◆ QueryNeighbours()

std::vector< int > Nektar::FieldUtils::Octree::QueryNeighbours ( int  nodeID)

Returns the IDs of the octants that surround the queried node. First, it finds the neighbouring nodes with the same or lower depth and, if they are not leaf nodes, return all the leaf octants contained in them. This means that, for octants of depth 2, this function returns all the leaf nodes in the tree except those lying inside the queried octant.

Parameters
nodeID
Returns
std::vector<int>

Definition at line 251 of file Octree.cpp.

252 {
253  std::vector<int> indices;
254  for (const OctantWeakPtr &node : m_nodes[nodeID]->GetNeighbours())
255  {
256  indices.push_back(node.lock()->GetID());
257  }
258  return indices;
259 }

References m_nodes.

Referenced by Nektar::FieldUtils::ProcessPhiFromFile::FindShortestDist().

◆ QueryNode()

int Nektar::FieldUtils::Octree::QueryNode ( const Array< OneD, NekDouble > &  coords,
int  depth = std::numeric_limits<int>::max() 
)

Given the coordinates 'coords' of a point, returns the leaf octant that contains it. If 'depth' is specified, returs the node that contains the point such that its depth is lower or equal to the one indicated. If the point lies outside the tree, it returns -1.

Parameters
coords
depth
Returns
int

Definition at line 138 of file Octree.cpp.

139 {
140  int nodeID = -1;
141 
142  if (coords.size())
143  {
144  // First, check if inside the octree
145  Array<OneD, NekDouble> bounds = m_root->GetBounds();
146  if ((coords[0] >= bounds[0]) && (coords[0] <= bounds[1]) &&
147  (coords[1] >= bounds[2]) && (coords[1] <= bounds[3]) &&
148  (coords[2] >= bounds[4]) && (coords[2] <= bounds[5]))
149  {
150  // Initialise 'node'
151  OctantSharedPtr node = m_root;
152 
153  // Keep advancing towards the end of the branch
154  while (!node->IsLeaf() && node->GetDepth() < depth)
155  {
156  int loc = node->GetLocInNode(coords);
157  node = node->GetChildren()[loc-1];
158  }
159 
160  nodeID = node->GetID();
161  }
162  }
163 
164  return nodeID;
165 }

References CG_Iterations::loc, and m_root.

Referenced by Nektar::FieldUtils::ProcessPhiFromFile::FindShortestDist(), QueryClosest(), and SetNeighbours().

◆ QueryNpoints()

int Nektar::FieldUtils::Octree::QueryNpoints ( int  nodeID)
inline

Definition at line 73 of file Octree.h.

73 { return m_nodes[nodeID]->GetNpoints(); }

References m_nodes.

◆ QueryPoints()

std::vector< int > Nektar::FieldUtils::Octree::QueryPoints ( int  nodeID)

Returns the indices of the points of the mesh contained in the tree.

Parameters
nodeID
Returns
std::vector<int>

Definition at line 236 of file Octree.cpp.

237 {
238  return m_nodes[nodeID]->GetIndices();
239 }

References m_nodes.

Referenced by Nektar::FieldUtils::ProcessPhiFromFile::FindShortestDist().

◆ SetNeighbours()

void Nektar::FieldUtils::Octree::SetNeighbours ( int  nodeID)
private

Once the nodes of the octree are created, sets their neighbours as explained in 'Octree::QueryNeighbours'.

Parameters
nodeID

Definition at line 312 of file Octree.cpp.

313 {
314  // Array with the different steps
315  static int steps[26][3] = {{-1,-1,-1}, {1,0,0}, {1,0,0}, {0,1,0}, {0,1,0},
316  {-1,0,0}, {-1,0,0}, {0,-1,0}, {1,0,0},
317  {-1,-1,1}, {1,0,0}, {1,0,0}, {0,1,0}, {0,1,0},
318  {-1,0,0}, {-1,0,0}, {0,-1,0}, {0,-1,1}, {1,0,0},
319  {1,0,0}, {0,1,0}, {0,1,0}, {-1,0,0}, {-1,0,0},
320  {0,-1,0}, {1,0,0}};
321 
322  // Advance to the leaves of the octree
323  if (!m_nodes[nodeID]->IsLeaf())
324  {
325  for (OctantSharedPtr child : m_nodes[nodeID]->GetChildren())
326  {
327  SetNeighbours(child->GetID());
328  }
329  }
330  else
331  {
332  // delta * steps
333  Array<OneD, NekDouble> probeCoords(m_nodes[nodeID]->GetCentre());
334  for (int step = 0; step < 26; ++step)
335  {
336  for (int i = 0; i < 3; ++i)
337  {
338  probeCoords[i] += m_nodes[nodeID]->GetDelta()*steps[step][i];
339  }
340 
341  // For each neighbour, find the leaves and add them
342  int neighInd = QueryNode(probeCoords, m_nodes[nodeID]->GetDepth());
343  if (neighInd > -1)
344  {
345  std::vector<OctantSharedPtr> leaves;
346  m_nodes[neighInd]->GetLeaves(leaves);
347  m_nodes[nodeID]->AddNeighbours(leaves);
348  }
349  }
350  }
351 }

References m_nodes, and QueryNode().

Referenced by Octree().

Member Data Documentation

◆ m_maxDepth

int Nektar::FieldUtils::Octree::m_maxDepth
private

Maximum depth of the tree.

Definition at line 153 of file Octree.h.

Referenced by AdvanceToStats(), GetStats(), and Octree().

◆ m_maxPts

int Nektar::FieldUtils::Octree::m_maxPts
private

Max points allowed in each octant.

Definition at line 145 of file Octree.h.

Referenced by GetStats(), and Octree().

◆ m_nLeaves

int Nektar::FieldUtils::Octree::m_nLeaves
private

Number of leaf nodes in the tree.

Definition at line 151 of file Octree.h.

Referenced by AdvanceToStats(), and GetStats().

◆ m_nMshPts

int Nektar::FieldUtils::Octree::m_nMshPts
private

Number of points in the mesh.

Definition at line 147 of file Octree.h.

Referenced by GetStats(), and Octree().

◆ m_nNodes

int Nektar::FieldUtils::Octree::m_nNodes
private

Number of octants in the tree.

Definition at line 149 of file Octree.h.

Referenced by GetStats(), and Octree().

◆ m_nodes

std::vector<OctantSharedPtr> Nektar::FieldUtils::Octree::m_nodes
private

Vector of pointers to every octant in the tree.

Definition at line 158 of file Octree.h.

Referenced by AdvanceToStats(), Octree(), QueryClosest(), QueryDelta(), QueryDepth(), QueryLocation(), QueryNeighbours(), QueryNpoints(), QueryPoints(), and SetNeighbours().

◆ m_root

OctantSharedPtr Nektar::FieldUtils::Octree::m_root
private

First node of the tree, linked to the rest.

Definition at line 156 of file Octree.h.

Referenced by Octree(), and QueryNode().