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.

49  : m_maxPts(0), m_nMshPts(0), m_nNodes(0), m_nLeaves(0), m_maxDepth(0),
50  m_root(nullptr)
51 {
52 }
OctantSharedPtr m_root
First node of the tree, linked to the rest.
Definition: Octree.h:204
int m_nNodes
Number of octants in the tree.
Definition: Octree.h:197
int m_nLeaves
Number of leaf nodes in the tree.
Definition: Octree.h:199
int m_maxPts
Max points allowed in each octant.
Definition: Octree.h:193
int m_maxDepth
Maximum depth of the tree.
Definition: Octree.h:201
int m_nMshPts
Number of points in the mesh.
Definition: Octree.h:195

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

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

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

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

288 {
289  // Update stats if we reached the end of the branch
290  if (m_nodes[nodeID]->IsLeaf())
291  {
292  m_nLeaves++;
293  m_maxDepth = (m_maxDepth > m_nodes[nodeID]->GetDepth())
294  ? m_maxDepth
295  : m_nodes[nodeID]->GetDepth();
296  }
297  // In any other case, dig into the tree
298  else
299  {
300  Array<OneD, OctantSharedPtr> children = m_nodes[nodeID]->GetChildren();
301  for (OctantSharedPtr child : children)
302  {
303  AdvanceToStats(child->GetID());
304  }
305  }
306 }
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 271 of file Octree.cpp.

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

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

181 {
182  int index = -1;
183  distance = std::numeric_limits<NekDouble>::max();
184 
185  if (coords.size())
186  {
187  // Find the corresponding node to 'coords'
188  int nodeInd;
189  if (pointInd > 0)
190  {
191  nodeInd = pointInd;
192  }
193  else
194  {
195  nodeInd = QueryNode(coords);
196  }
197 
198  // List the indices of all the candidate points
199  std::vector<int> indices(m_nodes[nodeInd]->GetIndices());
200  for (OctantWeakPtr neigh : m_nodes[nodeInd]->GetNeighbours())
201  {
202  for (int i : neigh.lock()->GetIndices())
203  {
204  indices.push_back(i);
205  }
206  }
207 
208  // Check the distances with all the nodes
209  for (int i : indices)
210  {
211  NekDouble sub = pts[i][0] - coords[0];
212  NekDouble tmpDistance = sub * sub;
213  for (int j = 1; j < 3; ++j)
214  {
215  sub = pts[i][j] - coords[j];
216  tmpDistance += sub * sub;
217  }
218  tmpDistance = std::sqrt(tmpDistance);
219 
220  if (distance > tmpDistance)
221  {
222  distance = tmpDistance;
223  index = i;
224  }
225  }
226  }
227 
228  return index;
229 }
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:139
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

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

◆ QueryDelta()

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

Definition at line 85 of file Octree.h.

86  {
87  return m_nodes[nodeID]->GetDelta();
88  }

References m_nodes.

◆ QueryDepth()

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

Definition at line 81 of file Octree.h.

82  {
83  return m_nodes[nodeID]->GetDepth();
84  }

References m_nodes.

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

◆ QueryLocation()

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

Definition at line 77 of file Octree.h.

78  {
79  return m_nodes[nodeID]->GetLoc();
80  }

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

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

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

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

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.

74  {
75  return m_nodes[nodeID]->GetNpoints();
76  }

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

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

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

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

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 201 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 193 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 199 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 195 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 197 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 206 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 204 of file Octree.h.

Referenced by Octree(), and QueryNode().