binaryTreeI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2016-2022 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "demandDrivenData.H"
27 
28 // * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
29 
30 inline void Foam::binaryTree::insertNode
31 (
32  chemPointISAT*& phi0,
33  binaryNode*& newNode
34 )
35 {
36  if (phi0 == phi0->node()->leafRight())// phi0 is on the right
37  {
38  phi0->node()->leafRight() = nullptr;
39  phi0->node()->nodeRight() = newNode;
40  return;
41  }
42  else if (phi0 == phi0->node()->leafLeft())// phi0 is on the left
43  {
44  phi0->node()->leafLeft() = nullptr;
45  phi0->node()->nodeLeft() = newNode;
46  return;
47 
48  }
49 
50  // if we reach this point, there is an issue with the addressing
52  << "trying to insert a node with a wrong pointer to a chemPoint"
53  << exit(FatalError);
54 }
55 
56 
57 inline void Foam::binaryTree::deleteSubTree(binaryNode* subTreeRoot)
58 {
59  if (subTreeRoot != nullptr)
60  {
61  deleteDemandDrivenData(subTreeRoot->leafLeft());
62  deleteDemandDrivenData(subTreeRoot->leafRight());
63  deleteSubTree(subTreeRoot->nodeLeft());
64  deleteSubTree(subTreeRoot->nodeRight());
65  deleteDemandDrivenData(subTreeRoot);
66  }
67 }
68 
69 
70 inline void Foam::binaryTree::deleteSubTree()
71 {
72  deleteSubTree(root_);
73 }
74 
75 
76 inline void Foam::binaryTree::transplant(binaryNode* u, binaryNode* v)
77 {
78  if (v != nullptr)
79  {
80  // u is root_
81  if (u->parent() == nullptr)
82  {
83  root_ = v;
84  }
85  // u is on the left of its parent
86  else if (u == u->parent()->nodeLeft())
87  {
88  u->parent()->nodeLeft() = v;
89  }
90  // u is ont the right of its parent
91  else if (u == u->parent()->nodeRight())
92  {
93  u->parent()->nodeRight() = v;
94  }
95  else
96  {
98  << "wrong addressing of the initial node"
99  << exit(FatalError);
100  }
101  v->parent() = u->parent();
102  }
103  else
104  {
106  << "trying to transplant a nullptr node"
107  << exit(FatalError);
108  }
109 }
110 
111 
112 inline Foam::chemPointISAT* Foam::binaryTree::chemPSibling(binaryNode* y)
113 {
114  if (y->parent() != nullptr)
115  {
116  if (y == y->parent()->nodeLeft())// y is on the left, return right side
117  {
118  // might return nullptr if the right side is a node
119  return y->parent()->leafRight();
120  }
121  else if (y == y->parent()->nodeRight())
122  {
123  return y->parent()->leafLeft();
124  }
125  else
126  {
128  << "wrong addressing of the initial node"
129  << exit(FatalError);
130  return nullptr;
131  }
132  }
133 
134  // the binaryNode is root_ and has no sibling
135  return nullptr;
136 }
137 
138 
139 inline Foam::chemPointISAT* Foam::binaryTree::chemPSibling(chemPointISAT* x)
140 {
141  if (size_>1)
142  {
143  if (x == x->node()->leafLeft())
144  {
145  // x is on the left, return right side
146  // might return nullptr if the right side is a node
147  return x->node()->leafRight();
148  }
149  else if (x == x->node()->leafRight())
150  {
151  // x is on the right, return left side
152  return x->node()->leafLeft();
153  }
154  else
155  {
157  << "wrong addressing of the initial leaf"
158  << exit(FatalError);
159  return nullptr;
160  }
161  }
162 
163  // there is only one leaf attached to the root_, no sibling
164  return nullptr;
165 }
166 
167 
168 inline Foam::binaryNode* Foam::binaryTree::nodeSibling(binaryNode* y)
169 {
170  if (y->parent()!=nullptr)
171  {
172  if (y == y->parent()->nodeLeft())
173  {
174  // y is on the left, return right side
175  return y->parent()->nodeRight();
176  }
177  else if (y == y->parent()->nodeRight())
178  {
179  return y->parent()->nodeLeft();
180  }
181  else
182  {
184  << "wrong addressing of the initial node"
185  << exit(FatalError);
186  return nullptr;
187  }
188  }
189  return nullptr;
190 }
191 
192 
193 Foam::binaryNode* Foam::binaryTree::nodeSibling(chemPointISAT* x)
194 {
195  if (size_>1)
196  {
197  if (x == x->node()->leafLeft())
198  {
199  // x is on the left, return right side
200  return x->node()->nodeRight();
201  }
202  else if (x == x->node()->leafRight())
203  {
204  // x is on the right, return left side
205  return x->node()->nodeLeft();
206  }
207  else
208  {
210  << "wrong addressing of the initial leaf"
211  << exit(FatalError);
212  return nullptr;
213  }
214  }
215  return nullptr;
216 }
217 
218 
219 inline void Foam::binaryTree::deleteAllNode(binaryNode* subTreeRoot)
220 {
221  if (subTreeRoot != nullptr)
222  {
223  deleteAllNode(subTreeRoot->nodeLeft());
224  deleteAllNode(subTreeRoot->nodeRight());
225  deleteDemandDrivenData(subTreeRoot);
226  }
227 }
228 
229 
230 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
231 
233 {
234  return size_;
235 }
236 
237 
239 {
240  // when we reach the leaf, we return 0
241  if (subTreeRoot == nullptr)
242  {
243  return 0;
244  }
245  else
246  {
247  return
248  1
249  + max
250  (
251  depth(subTreeRoot->nodeLeft()),
252  depth(subTreeRoot->nodeRight())
253  );
254  }
255 }
256 
257 
259 {
260  return depth(root_);
261 }
262 
263 
265 {
266  return root_;
267 }
268 
269 
271 {
272  return maxNLeafs_;
273 }
274 
275 
277 (
278  const scalarField& phiq,
279  binaryNode* node,
280  chemPointISAT*& nearest
281 )
282 {
283  if (size_ > 1)
284  {
285  scalar vPhi=0.0;
286  const scalarField& v = node->v();
287  const scalar& a = node->a();
288  // compute v*phi
289  for (label i=0; i<phiq.size(); i++) vPhi += phiq[i]*v[i];
290 
291 
292  if (vPhi > a) // on right side (side of the newly added point)
293  {
294  if (node->nodeRight()!=nullptr)
295  {
296  binaryTreeSearch(phiq, node->nodeRight(), nearest);
297  }
298  else // the terminal node is reached, store leaf on the right
299  {
300  nearest = node->leafRight();
301  return;
302  }
303  }
304  else // on left side (side of the previously stored point)
305  {
306  if (node->nodeLeft()!=nullptr)
307  {
308  binaryTreeSearch(phiq, node->nodeLeft(), nearest);
309  }
310  else // the terminal node is reached, return element on right
311  {
312  nearest = node->leafLeft();
313  return;
314  }
315  }
316  }
317  // only one point stored (left element of the root)
318  else if (size_ == 1)
319  {
320  nearest = root_->leafLeft();
321  }
322  else // no point stored
323  {
324  nearest = nullptr;
325  }
326 }
327 
328 
330 {
331  if (subTreeRoot!=nullptr)
332  {
333  while(subTreeRoot->nodeLeft() != nullptr)
334  {
335  subTreeRoot = subTreeRoot->nodeLeft();
336  }
337  return subTreeRoot->leafLeft();
338  }
339  else
340  {
341  return nullptr;
342  }
343 }
344 
345 
347 {
348  // Recursively delete the element in the subTree
349  deleteSubTree();
350 
351  // Reset root node (should already be nullptr)
352  root_ = nullptr;
353 
354  // Reset size_
355  size_ = 0;
356 }
357 
358 
360 {
361  return size_ >= maxNLeafs_;
362 }
363 
364 
366 {
367  // Has to go along each chemPointISAT of the tree
368  if (size_ > 0)
369  {
370  // First finds the first leaf
371  chemPointISAT* chP0 = treeMin();
372  chP0->resetNumRetrieve();
373 
374  // Then go to each successor
375  chemPointISAT* nextChP = treeSuccessor(chP0);
376  while (nextChP != nullptr)
377  {
378  nextChP->resetNumRetrieve();
379  nextChP = treeSuccessor(nextChP);
380  }
381  }
382 }
383 
384 
385 // ************************************************************************* //
void resetNumRetrieve()
Definition: binaryTreeI.H:365
layerAndWeight max(const layerAndWeight &a, const layerAndWeight &b)
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
Leaf of the binary tree. The chemPoint stores the composition &#39;phi&#39;, the mapping of this composition ...
binaryNode *& node()
const scalar & a() const
Definition: binaryNode.H:170
chemPointISAT * treeSuccessor(chemPointISAT *x)
Definition: binaryTree.C:456
label size() const
Member functions.
Definition: binaryTreeI.H:232
binaryNode *& nodeLeft()
Definition: binaryNode.H:148
void binaryTreeSearch(const scalarField &phiq, binaryNode *node, chemPointISAT *&nearest)
Definition: binaryTreeI.H:277
label maxNLeafs() const
Definition: binaryTreeI.H:270
chemPointISAT * treeMin()
Definition: binaryTree.H:205
void clear()
Removes every entries of the tree and delete the associated objects.
Definition: binaryTreeI.H:346
Node of the binary tree.
Definition: binaryNode.H:48
chemPointISAT *& leafRight()
Definition: binaryNode.H:143
label depth() const
Definition: binaryTreeI.H:258
void resetNumRetrieve()
Resets the number of retrieves at each time step.
binaryNode * root()
Definition: binaryTreeI.H:264
Template functions to aid in the implementation of demand driven data.
binaryNode *& nodeRight()
Definition: binaryNode.H:153
binaryNode *& parent()
Definition: binaryNode.H:158
bool isFull()
ListFull.
Definition: binaryTreeI.H:359
const scalarField & v() const
Topology.
Definition: binaryNode.H:165
void deleteDemandDrivenData(DataPtr &dataPtr)
void deleteAllNode()
Definition: binaryTree.H:198
chemPointISAT *& leafLeft()
Access.
Definition: binaryNode.H:138