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