Save memory in BTree, count number of leaves and nodes

This commit is contained in:
Matthias Hochsteger 2019-09-26 14:02:37 +02:00
parent b2808109b6
commit 7b1c05f12c

View File

@ -8,6 +8,7 @@ namespace netgen
template<int dim, typename T=INDEX> template<int dim, typename T=INDEX>
class BTree class BTree
{ {
public:
// Number of entries per leaf // Number of entries per leaf
static constexpr int N = 100; static constexpr int N = 100;
@ -34,40 +35,67 @@ namespace netgen
struct Node struct Node
{ {
double sep; union
Node *left, *right; {
Node *children[2];
Leaf *leaf; Leaf *leaf;
};
double sep;
int level; int level;
Node() = default; Node()
: children{nullptr,nullptr}
{ }
~Node() ~Node()
{ {
if(children[1])
{
delete children[0];
delete children[1];
}
else
delete leaf; delete leaf;
delete left; }
delete right;
Leaf *GetLeaf() const
{
return children[1] ? nullptr : leaf;
} }
}; };
private:
Node root; Node root;
Array<Leaf*, INDEX> leaf_index; Array<Leaf*, INDEX> leaf_index;
Point<dim> global_min, global_max; Point<dim> global_min, global_max;
double tol; double tol;
size_t n_leaves;
size_t n_nodes;
public: public:
BTree (const Point<dim> & pmin, const Point<dim> & pmax) BTree (const Point<dim> & pmin, const Point<dim> & pmax)
: global_min(pmin), global_max(pmax) : global_min(pmin), global_max(pmax), n_leaves(1), n_nodes(1)
{ {
root.leaf = new Leaf(); root.leaf = new Leaf();
root.level = 0; root.level = 0;
tol = 1e-7 * Dist(pmax, pmin); tol = 1e-7 * Dist(pmax, pmin);
} }
size_t GetNLeaves()
{
return n_leaves;
}
size_t GetNNodes()
{
return n_nodes;
}
void GetIntersecting (const Point<dim> & pmin, const Point<dim> & pmax, void GetIntersecting (const Point<dim> & pmin, const Point<dim> & pmax,
NgArray<T> & pis) const NgArray<T> & pis) const
{ {
static Array<const Node*> stack(1000); static Array<const Node*> stack(1000);
static Array<int> dir_stack(1000); static Array<int> dir_stack(1000);
static NgArray<T> ref_pis;
pis.SetSize(0); pis.SetSize(0);
@ -95,7 +123,7 @@ namespace netgen
int dir = dir_stack.Last(); int dir = dir_stack.Last();
dir_stack.DeleteLast(); dir_stack.DeleteLast();
if(Leaf *leaf=node->leaf) if(Leaf *leaf = node->GetLeaf())
{ {
for (auto i : IntRange(leaf->n_elements)) for (auto i : IntRange(leaf->n_elements))
{ {
@ -117,12 +145,12 @@ namespace netgen
if(newdir==2*dim) newdir = 0; if(newdir==2*dim) newdir = 0;
if (tpmin[dir] <= node->sep) if (tpmin[dir] <= node->sep)
{ {
stack.Append(node->left); stack.Append(node->children[0]);
dir_stack.Append(newdir); dir_stack.Append(newdir);
} }
if (tpmax[dir] >= node->sep) if (tpmax[dir] >= node->sep)
{ {
stack.Append(node->right); stack.Append(node->children[1]);
dir_stack.Append(newdir); dir_stack.Append(newdir);
} }
} }
@ -140,15 +168,15 @@ namespace netgen
} }
Node * node = &root; Node * node = &root;
Leaf * leaf = node->leaf; Leaf * leaf = node->GetLeaf();
// search correct leaf to add point // search correct leaf to add point
while(!leaf) while(!leaf)
{ {
node = p[dir] < node->sep ? node->left : node->right; node = p[dir] < node->sep ? node->children[0] : node->children[1];
dir++; dir++;
if(dir==2*dim) dir = 0; if(dir==2*dim) dir = 0;
leaf = node->leaf; leaf = node->GetLeaf();
} }
// add point to leaf // add point to leaf
@ -186,9 +214,8 @@ namespace netgen
node2->leaf = leaf2; node2->leaf = leaf2;
node2->level = node->level+1; node2->level = node->level+1;
node->left = node1; node->children[0] = node1;
node->right = node2; node->children[1] = node2;
node->leaf = nullptr;
node->sep = 0.5 * (leaf->p[order[isplit-1]][dir] + leaf->p[order[isplit]][dir]); node->sep = 0.5 * (leaf->p[order[isplit-1]][dir] + leaf->p[order[isplit]][dir]);
// add new point to one of the new leaves // add new point to one of the new leaves
@ -198,6 +225,8 @@ namespace netgen
leaf2->Add( leaf_index, p, pi ); leaf2->Add( leaf_index, p, pi );
delete leaf; delete leaf;
n_leaves++;
n_nodes+=2;
} }
} }
@ -891,6 +920,8 @@ namespace netgen
PrintMessage (3, "Points: ", cntp); PrintMessage (3, "Points: ", cntp);
PrintMessage (3, "Elements: ", tempels.Size()); PrintMessage (3, "Elements: ", tempels.Size());
PrintMessage (3, "Tree data entries per element: ", 1.0*tettree.N*tettree.GetNLeaves() / tempels.Size());
PrintMessage (3, "Tree nodes per element: ", 1.0*tettree.GetNNodes() / tempels.Size());
// (*mycout) << cntp << " / " << tempels.Size() << " points/elements" << endl; // (*mycout) << cntp << " / " << tempels.Size() << " points/elements" << endl;
/* /*