/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
    \\  /    A nd           | www.openfoam.com
     \\/     M anipulation  |
-------------------------------------------------------------------------------
    Copyright (C) 2016-2017 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.

Class
    Foam::binaryNode

Description
    Node of the binary tree

SourceFile
    binaryNode.C

\*---------------------------------------------------------------------------*/

#ifndef binaryNode_H
#define binaryNode_H

#include "chemPointISAT.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

namespace Foam
{

/*---------------------------------------------------------------------------*\
                           Class binaryNode Declaration
\*---------------------------------------------------------------------------*/

template<class CompType, class ThermoType>
class binaryNode
{

public:

    //- Element on the left
    chemPointISAT<CompType, ThermoType>* leafLeft_;

    //- Element on the right
    chemPointISAT<CompType, ThermoType>* leafRight_;

    //- Node which follows on the left
    binaryNode<CompType, ThermoType>* nodeLeft_;

    //- Node which follows on the right
    binaryNode<CompType, ThermoType>* nodeRight_;

    //- Parent node
    binaryNode<CompType, ThermoType>* parent_;

    //- Number of equations in addition to the species eqs.
    label nAdditionalEqns_;

    scalarField v_;

    scalar a_;

    //- Compute vector v:
    //  Let E be the ellipsoid which covers the region of accuracy of
    //  the left leaf (previously defined). E is described by
    //  E={phi| ||L^T.(phi-phi0)|| <= 1}, (see chemPoint for more details).
    //  let E' be the transformation of E in a space where E' is a hypersphere
    //  centered at the origin, in this space y=L^T.(phi-phi0) and then
    //  E'={y| ||y||<=1}
    //  let u be the unit vector joining the center of E' and the newly added
    //  composition point in the transformed space
    //  (y2=L^T.(phiq-phi0)),u = y2/||y2|
    //  Then the hyperplane separating the two points is defined as the
    //  perpendicular bisector of the segment linking 0 to y2
    //      H' = {y| u^T.(y-yh) = 0},
    //  where yh = y2/2.
    //  In the original composition space, the hyperplane H is defined by
    //      H = {y| v^T(phi-phih) = 0},
    //  where phih = phi0 + L^-T.yh = (phi0 + phiq) / 2 and v is
    //            L.L^T (phiq-phi0)
    //      v = -------------------- .
    //          ||L.L^T (phiq-phi0)||
    //
    //  Note :  v is not normalised in this implementation since it is used
    //              on both side of an equality to know if one should go on the
    //              left or the right in the binary tree
    //  Parameter:
    //      elementLeft : chemPoint of the left element
    //      elementRight: chemPoint of the right element
    //       v : empty scalar field to store v
    //  Return: void (v is stored in the empty scalarField)
    void calcV
    (
        chemPointISAT<CompType, ThermoType>*& elementLeft,
        chemPointISAT<CompType, ThermoType>*& elementRight,
        scalarField& v
    );

    //- Compute a the product v^T.phih, with phih = (phi0 + phiq)/2.
    //  When travelling in the binary tree,
    //  to know in which part of the composition space the query point 'phi'
    //  belongs to, v^T.phi is performed. If the result is "> a" then it belongs
    //  to the right part (where phiq is), otherwise it belongs to the left
    // part (where phi0 is).
    scalar calcA
    (
        chemPointISAT<CompType, ThermoType>* elementLeft,
        chemPointISAT<CompType, ThermoType>* elementRight
    );

    // Constructors

        //- Construct null
        binaryNode();

        //- Construct from components
        binaryNode
        (
            chemPointISAT<CompType, ThermoType>* elementLeft,
            chemPointISAT<CompType, ThermoType>* elementRight,
            binaryNode<CompType, ThermoType>* parent
        );


    // Member functions

        //- Access

        inline chemPointISAT<CompType, ThermoType>*& leafLeft()
        {
            return leafLeft_;
        }

        inline chemPointISAT<CompType, ThermoType>*& leafRight()
        {
            return leafRight_;
        }

        inline binaryNode<CompType, ThermoType>*& nodeLeft()
        {
            return nodeLeft_;
        }

        inline binaryNode<CompType, ThermoType>*& nodeRight()
        {
            return nodeRight_;
        }

        inline binaryNode<CompType, ThermoType>*& parent()
        {
            return parent_;
        }

        //- Topology

        inline const scalarField& v() const
        {
            return v_;
        }

        inline scalarField& v()
        {
            return v_;
        }

        inline const scalar& a() const
        {
            return a_;
        }

        inline scalar& a()
        {
            return a_;
        }
};


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

} // End namespace Foam

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#ifdef NoRepository
    #include "binaryNode.C"
#endif

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

#endif

// ************************************************************************* //
