35template<
class CompType,
class ThermoType>
36void Foam::binaryTree<CompType, ThermoType>::insertNode
42 if (phi0 ==
phi0->node()->leafRight())
45 phi0->node()->leafRight() =
nullptr;
46 phi0->node()->nodeRight() = newNode;
49 else if (phi0 ==
phi0->node()->leafLeft())
52 phi0->node()->leafLeft() =
nullptr;
53 phi0->node()->nodeLeft() = newNode;
60 <<
"trying to insert a node with a wrong pointer to a chemPoint"
65template<
class CompType,
class ThermoType>
66bool Foam::binaryTree<CompType, ThermoType>::inSubTree
68 const scalarField& phiq,
73 if ((n2ndSearch_ < max2ndSearch_) && (
y !=
nullptr))
77 const scalar a =
y->a();
80 for (label i=0; i<phiq.size(); ++i)
87 if (
y->nodeLeft() ==
nullptr)
91 if (
y->leafLeft()->inEOA(phiq))
100 if (inSubTree(phiq,
y->nodeLeft(),
x))
107 if ((n2ndSearch_ < max2ndSearch_) &&
y->nodeRight() ==
nullptr)
111 if (
y->leafRight()->inEOA(phiq))
124 return inSubTree(phiq,
y->nodeRight(),
x);
130 if (
y->nodeRight() ==
nullptr)
133 if (
y->leafRight()->inEOA(phiq))
140 if (inSubTree(phiq,
y->nodeRight(),
x))
149 if ((n2ndSearch_ < max2ndSearch_) &&
y->nodeLeft() ==
nullptr)
152 if (
y->leafLeft()->inEOA(phiq))
164 return inSubTree(phiq,
y->nodeLeft(),
x);
172template<
class CompType,
class ThermoType>
173void Foam::binaryTree<CompType, ThermoType>::deleteSubTree(node* subTreeRoot)
175 if (subTreeRoot !=
nullptr)
179 deleteSubTree(subTreeRoot->nodeLeft());
180 deleteSubTree(subTreeRoot->nodeRight());
186template<
class CompType,
class ThermoType>
187void Foam::binaryTree<CompType, ThermoType>::transplant(node* u, node* v)
192 if (u->parent() ==
nullptr)
197 else if (u == u->parent()->nodeLeft())
199 u->parent()->nodeLeft() = v;
202 else if (u == u->parent()->nodeRight())
204 u->parent()->nodeRight() = v;
209 <<
"wrong addressing of the initial node"
212 v->parent() = u->parent();
217 <<
"trying to transplant a nullptr node"
223template<
class CompType,
class ThermoType>
225Foam::binaryTree<CompType, ThermoType>::chemPSibling(node*
y)
227 if (
y->parent() !=
nullptr)
229 if (
y ==
y->parent()->nodeLeft())
232 return y->parent()->leafRight();
234 else if (
y ==
y->parent()->nodeRight())
236 return y->parent()->leafLeft();
240 <<
"wrong addressing of the initial node"
249template<
class CompType,
class ThermoType>
251Foam::binaryTree<CompType, ThermoType>::chemPSibling(chemPoint*
x)
255 if (
x ==
x->node()->leafLeft())
259 return x->node()->leafRight();
261 else if (
x ==
x->node()->leafRight())
264 return x->node()->leafLeft();
268 <<
"wrong addressing of the initial leaf"
277template<
class CompType,
class ThermoType>
279Foam::binaryTree<CompType, ThermoType>::nodeSibling(node*
y)
281 if (
y->parent() !=
nullptr)
283 if (
y ==
y->parent()->nodeLeft())
286 return y->parent()->nodeRight();
288 else if (
y ==
y->parent()->nodeRight())
290 return y->parent()->nodeLeft();
294 <<
"wrong addressing of the initial node"
302template<
class CompType,
class ThermoType>
304Foam::binaryTree<CompType, ThermoType>::nodeSibling(chemPoint*
x)
308 if (
x ==
x->node()->leafLeft())
311 return x->node()->nodeRight();
313 else if (
x ==
x->node()->leafRight())
316 return x->node()->nodeLeft();
320 <<
"wrong addressing of the initial leaf"
328template<
class CompType,
class ThermoType>
331 if (subTreeRoot !=
nullptr)
333 deleteAllNode(subTreeRoot->nodeLeft());
334 deleteAllNode(subTreeRoot->nodeRight());
342template<
class CompType,
class ThermoType>
345 TDACChemistryModel<CompType, ThermoType>&
chemistry,
351 maxNLeafs_(coeffsDict.get<label>(
"maxNLeafs")),
354 max2ndSearch_(coeffsDict.getOrDefault(
"max2ndSearch", 0)),
355 coeffsDict_(coeffsDict)
360template<
class CompType,
class ThermoType>
364 if (subTreeRoot ==
nullptr)
374 depth(subTreeRoot->nodeLeft()),
381template<
class CompType,
class ThermoType>
384 const scalarField& phiq,
385 const scalarField& Rphiq,
386 const scalarSquareMatrix&
A,
387 const scalarField& scaleFactor,
388 const scalar& epsTol,
399 chemPoint* newChemPoint =
412 root_->leafLeft() = newChemPoint;
419 binaryTreeSearch(phiq, root_, phi0);
422 node* parentNode =
phi0->node();
426 chemPoint* newChemPoint =
445 newNode =
new node(phi0, newChemPoint, parentNode);
447 insertNode(phi0, newNode);
453 newNode =
new node(phi0, newChemPoint,
nullptr);
457 phi0->node() = newNode;
458 newChemPoint->node()=newNode;
465template<
class CompType,
class ThermoType>
468 const scalarField& phiq,
476 const scalarField& v = node->v();
477 const scalar& a = node->a();
479 for (label i=0; i<phiq.size(); ++i)
481 vPhi += phiq[i]*v[i];
487 if (node->nodeRight() !=
nullptr)
489 binaryTreeSearch(phiq, node->nodeRight(), nearest);
493 nearest = node->leafRight();
499 if (node->nodeLeft() !=
nullptr)
501 binaryTreeSearch(phiq, node->nodeLeft(), nearest);
505 nearest = node->leafLeft();
513 nearest = root_->leafLeft();
522template<
class CompType,
class ThermoType>
525 const scalarField& phiq,
531 if ((n2ndSearch_ < max2ndSearch_) && (size_ > 1))
533 chemPoint* xS = chemPSibling(
x);
543 else if (inSubTree(phiq, nodeSibling(
x),
x))
551 while ((
y->parent()!=
nullptr) && (n2ndSearch_ < max2ndSearch_))
553 xS = chemPSibling(
y);
563 else if (inSubTree(phiq, nodeSibling(
y),
x))
580template<
class CompType,
class ThermoType>
585 deleteDemandDrivenData(phi0);
586 deleteDemandDrivenData(root_);
590 node* z =
phi0->node();
592 chemPoint* siblingPhi0 = chemPSibling(phi0);
594 if (siblingPhi0 !=
nullptr)
597 if (z->parent() ==
nullptr)
600 root_->leafLeft()=siblingPhi0;
601 siblingPhi0->node()=root_;
603 else if (z == z->parent()->nodeLeft())
605 z->parent()->leafLeft() = siblingPhi0;
606 z->parent()->nodeLeft() =
nullptr;
607 siblingPhi0->node() = z->parent();
609 else if (z == z->parent()->nodeRight())
611 z->parent()->leafRight() = siblingPhi0;
612 z->parent()->nodeRight() =
nullptr;
613 siblingPhi0->node() = z->parent();
618 <<
"wrong addressing of the initial leaf"
624 x = nodeSibling(phi0);
632 <<
"inconsistent structure of the tree, no leaf and no node"
644template<
class CompType,
class ThermoType>
649 chemPoint*
x = treeMin();
650 List<chemPoint*> chemPoints(size_);
651 label chemPointi = 0;
654 label
n =
x->phi().size();
655 scalarField mean(
n, Zero);
658 const scalarField& phij =
x->phi();
660 chemPoints[chemPointi++] =
x;
661 x = treeSuccessor(
x);
663 mean /= scalar(size_);
666 List<scalar> variance(
n, Zero);
672 variance[vi] +=
sqr(phij[vi] - mean[vi]);
677 scalar maxVariance(-1.0);
681 if (maxVariance < variance[vi])
683 maxVariance = variance[vi];
692 SortableList<scalar> phiMaxDir(chemPoints.size(), Zero);
695 phiMaxDir[j] = chemPoints[j]->phi()[maxDir];
704 node* newNode =
new node
706 chemPoints[phiMaxDir.indices()[0]],
707 chemPoints[phiMaxDir.indices()[phiMaxDir.size()-1]],
712 chemPoints[phiMaxDir.indices()[0]]->node() = newNode;
713 chemPoints[phiMaxDir.indices()[phiMaxDir.size()-1]]->node() = newNode;
715 for (label cpi=1; cpi<chemPoints.size()-1; ++cpi)
720 chemPoints[phiMaxDir.indices()[cpi]]->phi(),
726 new node(phi0, chemPoints[phiMaxDir.indices()[cpi]],
phi0->node());
728 insertNode(phi0, nodeToAdd);
729 phi0->node() = nodeToAdd;
730 chemPoints[phiMaxDir.indices()[cpi]]->node() = nodeToAdd;
735template<
class CompType,
class ThermoType>
739 if (subTreeRoot !=
nullptr)
741 while (subTreeRoot->nodeLeft() !=
nullptr)
743 subTreeRoot = subTreeRoot->nodeLeft();
745 return subTreeRoot->leafLeft();
752template<
class CompType,
class ThermoType>
758 if (
x ==
x->node()->leafLeft())
760 if (
x->node()->nodeRight() ==
nullptr)
762 return x->node()->leafRight();
766 return treeMin(
x->node()->nodeRight());
769 else if (
x ==
x->node()->leafRight())
772 while ((
y->parent() !=
nullptr))
774 if (
y ==
y->parent()->nodeLeft())
776 if (
y->parent()->nodeRight() ==
nullptr)
778 return y->parent()->leafRight();
782 return treeMin(
y->parent()->nodeRight());
795 <<
"inconsistent structure of the tree, no leaf and no node"
803template<
class CompType,
class ThermoType>
817template<
class CompType,
class ThermoType>
820 return size_ >= maxNLeafs_;
824template<
class CompType,
class ThermoType>
831 chemPoint* chemPoint0 = treeMin();
832 chemPoint0->resetNumRetrieve();
835 chemPoint* nextchemPoint = treeSuccessor(chemPoint0);
836 while (nextchemPoint !=
nullptr)
838 nextchemPoint->resetNumRetrieve();
839 nextchemPoint = treeSuccessor(nextchemPoint);
static const Foam::dimensionedScalar A("", Foam::dimPressure, 611.21)
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
A list that is sorted upon construction or when explicitly requested with the sort() method.
const labelList & indices() const noexcept
Return the list of sorted indices. Updated every sort.
void sort()
Forward (stable) sort the list (if changed after construction).
Extends StandardChemistryModel by adding the TDAC method.
void size(const label n)
Older name for setAddressableSize.
binaryNode< CompType, ThermoType > *& nodeLeft()
binaryNode< CompType, ThermoType > *& parent()
binaryNode< CompType, ThermoType > *& nodeRight()
chemPointISAT< CompType, ThermoType > *& leafLeft()
Access.
void deleteLeaf(chemPoint *&phi0)
Delete a leaf from the binary tree and reshape the binary tree for.
void binaryTreeSearch(const scalarField &phiq, node *node, chemPoint *&nearest)
void insertNewLeaf(const scalarField &phiq, const scalarField &Rphiq, const scalarSquareMatrix &A, const scalarField &scaleFactor, const scalar &epsTol, const label nCols, chemPoint *&phi0)
chemPoint * treeSuccessor(chemPoint *x)
binaryTree(TDACChemistryModel< CompType, ThermoType > &chemistry, dictionary coeffsDict)
Construct from dictionary and chemistryOnLineLibrary.
chemPointISAT< CompType, ThermoType > chemPoint
void clear()
Removes every entries of the tree and delete the associated objects.
chemPoint * treeMin(node *subTreeRoot)
binaryNode< CompType, ThermoType > node
label depth(node *subTreeRoot)
Computes iteratively the depth of the subTree.
void balance()
Cheap balance function.
bool secondaryBTSearch(const scalarField &phiq, chemPoint *&x)
Leaf of the binary tree. The chemPoint stores the composition 'phi', the mapping of this composition ...
void resetNumRetrieve()
Resets the number of retrieves at each time step.
bool inEOA(const scalarField &phiq)
To RETRIEVE the mapping from the stored chemPoint phi, the query.
binaryNode< CompType, ThermoType > *& node()
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
BasicChemistryModel< psiReactionThermo > & chemistry
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const dimensionedScalar phi0
Magnetic flux quantum: default SI units: [Wb].
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
SquareMatrix< scalar > scalarSquareMatrix
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
errorManipArg< error, int > exit(error &err, const int errNo=1)
void deleteDemandDrivenData(DataPtr &dataPtr)
#define forAll(list, i)
Loop across all elements in list.