/*---------------------------------------------------------------------------*\
  ==  == ====== ====   ====    |
                    \\     ||  | Multiphase Code Repository by HZDR
  ======   //   ||  || ===//   | Website: https://doi.org/10.14278/rodare.767
  ||  ||  //    ||  // || \\   | License: GPL-3.0-or-later
  ==  == ====== ====   ==  ==  |
-------------------------------------------------------------------------------
License
    This file is part of the Multiphase Code Repository by HZDR.

    Copyright (C) 2025 by Helmholtz-Zentrum Dresden-Rossendorf e.V. (HZDR),
    Website: https://hzdr.de

    Copyright (C) 2025 by Technische Universitaet Darmstadt,
    Website: https://www.tu-darmstadt.de

    Copyright (C) 2025 by Technische Universitaet Muenchen,
    Website: https://www.tum.de

    Multiphase Code Repository by HZDR is based on the free software for
    computational fluid dynamics (CFD) from the OpenFOAM Foundation.
    Copyright (C) 2025 by OpenFOAM Foundation, Website: https://openfoam.org

    If you are interested in which files are original OpenFOAM Foundation
    files, which OpenFOAM Foundation files were modified, and which files were
    newly created, see FILES.md.

    Multiphase Code Repository by HZDR 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.

    Multiphase Code Repository by HZDR 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 the Multiphase Code Repository by HZDR. If not, see
    <http://www.gnu.org/licenses/>.

Class
    Foam::functionObjects::phaseStructureProperties

Description
    Calculates and outputs the centre of gravity, velocity, volume, surface area
    and sphericity of a phase and can be used to determine the rise velocity
    and shape of a gas structure in stagnant liquid for example.

    Surface area is calculated via continuous interface reconstruction,
    according to Kunkelmann (2011).

    The dimensionality of the case is determined automatically.

    Reference:
    \verbatim
        Kunkelmann, C. (2011).
        Numerical modeling and investigation of boiling phenomena.
        PhD Thesis, Technische Universit{\"a}t Darmstadt, 1-122.
    \endverbatim

    Example of function object specification:
    \verbatim
    bubble.
    {
        type            phaseStructureProperties;
        libs            ("libaddonFieldFunctionObjects.so");
        writeControl    runTime;
        writeInterval   1;
        ...
        cellZone        all;
        alpha           alpha.air;
        U               U.air;
        threshold       0.5;
        calcSphericity  true;
    }
    \endverbatim

Usage
    \table
        Property      | Description                        | Required  | Default
        type          | type name: phaseStructureProperties| yes         |
        select        | Evaluate for 'cellZone' or 'all'   | only if 'all'|
        cellZone      | Specify cellZone                   | if 'cellZone'|
        alpha         | Phase volume fraction              | yes         |
        U             | Phase specific velocity            | no          | U
        threshold     | Value for definition of interface  | no          | 0.5
        calcSphericity| Switch to turn on/off Sphericity   | no          | true
    \endtable

See also
    Foam::functionObjects::fvMeshFunctionObject
    Foam::functionObjects::logFiles

SourceFiles
    phaseStructureProperties.C

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

#ifndef functionObjects_phaseStructureProperties_H
#define functionObjects_phaseStructureProperties_H

#include "fvMeshFunctionObject.H"
#include "fvCellZone.H"
#include "logFiles.H"
#include "NamedEnum.H"
#include "dimensionedVector.H"
#include "volFieldsFwd.H"

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

namespace Foam
{
namespace functionObjects
{

/*---------------------------------------------------------------------------*\
                  Class phaseStructureProperties Declaration
\*---------------------------------------------------------------------------*/

class phaseStructureProperties
:
    public fvMeshFunctionObject,
    public logFiles
{
private:

    // Private Member Functions

        //- Disallow default bitwise copy construct
        phaseStructureProperties(const phaseStructureProperties&);

        //- Disallow default bitwise assignment
        void operator=(const phaseStructureProperties&);

        //- Interpolate cell centred values to node values by inverse distance
        tmp<scalarField> interpolateCellDataToPointData
        (
            const volScalarField&
        ) const;

        //- Calculate surface area of iso-surface of given threshold
        scalarField surfaceArea(const scalarField&, const scalar);

        //- Register a dimensioned<Type> as UniformDimensionedField<Type> with
        //  the given name
        template<class Type>
        void
        registerDimensionedObject(const word, const dimensioned<Type>&)const;


protected:

    // Protected data

        //- Construction dictionary
        const dictionary dict_;

        //- The cellZone to operate on
        fvCellZone zone_;

        //- Global number of cells
        label nCells_;

        //- Local list of cell IDs
        labelList cellId_;

        //- Name of phase fraction field
        word alphaName_;

        //- Name of phase velocity field
        word velocityName_;

        //- Whether to calculate and write surface area and sphericity
        Switch calcSphericity_;

        //- Value for interface definition
        scalar threshold_;

        //- Two dimensional domain
        bool twoDimensional_;

        //- For 2D cases: thickness of domain in 3rd direction
        dimensionedScalar thickness_;

        //- Centre of gravity
        dimensionedVector CG_;

        //- Velocity
        dimensionedVector velocity_;

        //- Volume of the phase region
        dimensionedScalar volume_;

        //- Surface area of the phase region
        dimensionedScalar area_;

        //- Sphericity
        dimensionedScalar sphericity_;


    // Protected Member Functions

        //- Combine fields from all processor domains into single field
        template<class Type>
        void combineFields(Field<Type>& field);

        //- Output file header information
        virtual void writeFileHeader(const label i);


public:

    //- Run-time type information
    TypeName("phaseStructureProperties");


    // Constructors

        //- Construct from name, time and dictionary
        phaseStructureProperties
        (
            const word& name,
            const Time& runTime,
            const dictionary& dict
        );


    //- Destructor
    virtual ~phaseStructureProperties();


    // Member Functions

        //- Return the reference to the construction dictionary
        inline const dictionary& dict() const;

        //- Helper function to return the reference to the mesh
        inline const fvMesh& mesh() const;

        //- Filter a field according to cellIds
        template<class Type>
        tmp<Field<Type>> filterField(const Field<Type>& field) const;

        //- Read from dictionary
        virtual bool read(const dictionary&);

        //- Return the list of fields required
        virtual wordList fields() const
        {
            return wordList::null();
        }

        //- Execute, currently does nothing
        virtual bool execute();

        //- Calculate and write
        virtual bool write();
};


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

} // End namespace functionObjects
} // End namespace Foam

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

#include "phaseStructurePropertiesI.H"

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

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

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

#endif

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