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

Member Typedef Documentation

◆ OctantSharedPtr

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

Definition at line 46 of file Octree.h.

◆ OctantWeakPtr

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

Definition at line 47 of file Octree.h.

Constructor & Destructor Documentation

◆ Octree() [1/3]

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

Construct a new octree object.

Definition at line 46 of file Octree.cpp.

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

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

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

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

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

286{
287 // Update stats if we reached the end of the branch
288 if (m_nodes[nodeID]->IsLeaf())
289 {
290 m_nLeaves++;
291 m_maxDepth = (m_maxDepth > m_nodes[nodeID]->GetDepth())
292 ? 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:46

References AdvanceToStats(), m_maxDepth, m_nLeaves, and m_nodes.

Referenced by AdvanceToStats(), and 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 269 of file Octree.cpp.

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

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

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

84 {
85 return m_nodes[nodeID]->GetDelta();
86 }

References m_nodes.

◆ QueryDepth()

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

Definition at line 79 of file Octree.h.

80 {
81 return m_nodes[nodeID]->GetDepth();
82 }

References m_nodes.

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

◆ QueryLocation()

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

Definition at line 75 of file Octree.h.

76 {
77 return m_nodes[nodeID]->GetLoc();
78 }

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

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

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

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

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

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

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

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

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

References m_nodes, QueryNode(), and SetNeighbours().

Referenced by Octree(), and SetNeighbours().

Member Data Documentation

◆ m_maxDepth

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

Maximum depth of the tree.

Definition at line 199 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 191 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 197 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 193 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 195 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 204 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 202 of file Octree.h.

Referenced by Octree(), and QueryNode().