/*---------------------------------------------------------------------------*\
  ==  == ====== ====   ====    |
                    \\     ||  | 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

    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::resolvedInterfaceSystem

Description
    Class which provides functionality for modelling resolved interfaces.

SourceFiles
    resolvedInterfaceSystem.C

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

#ifndef resolvedInterfaceSystem_H
#define resolvedInterfaceSystem_H

#include "phaseSystem.H"
#include "segregatedPhaseInterface.H"
#include "HashPtrTable.H"

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

namespace Foam
{

// Forward declaration of classes
class interfaceCompressionModel;
class surfaceTensionForceModel;
class subGridSurfaceTensionModel;
class interfaceIndicatorMethod;
class underResolutionModel;
class clusterTrackingModel;
class moveAlphaByPotentialModel;

/*---------------------------------------------------------------------------*\
                   Class resolvedInterfaceSystem Declaration
\*---------------------------------------------------------------------------*/

class resolvedInterfaceSystem
:
    public regIOobject
{
    // Private Type Definitions

        typedef HashPtrTable
        <
            interfaceCompressionModel,
            phaseInterfaceKey,
            phaseInterfaceKey::hash
        > interfaceCompressionModelTable;

        typedef HashPtrTable
        <
            subGridSurfaceTensionModel,
            phaseInterfaceKey,
            phaseInterfaceKey::hash
        > subGridSurfaceTensionModelTable;

        typedef HashPtrTable
        <
            underResolutionModel,
            phaseInterfaceKey,
            phaseInterfaceKey::hash
        > underResolutionModelTable;

        typedef HashPtrTable
        <
            clusterTrackingModel,
            phaseInterfaceKey,
            phaseInterfaceKey::hash
        > clusterTrackingModelTable;

        typedef HashPtrTable
        <
            moveAlphaByPotentialModel,
            phaseInterfaceKey,
            phaseInterfaceKey::hash
        > moveAlphaByPotentialModelTable;

        //- Partial list of phase models
        typedef UPtrList<phaseModel> phaseModelPartialList;


    // Private Data

        //- Reference to the phase system
        const phaseSystem& fluid_;

        //- Interface compression models
        const interfaceCompressionModelTable interfaceCompressionModels_;

        //- Surface tension force model
        const autoPtr<surfaceTensionForceModel> surfaceTensionForceModel_;

        //- Sub-grid surface tension models
        const subGridSurfaceTensionModelTable subGridSurfaceTensionModels_;

        //- Resolved interface detection method
        const autoPtr<interfaceIndicatorMethod> interfaceIndicatorMethod_;

        //- Under-resolution models
        const underResolutionModelTable underResolutionModels_;

        //- Models for cluster tracking
        clusterTrackingModelTable clusterTrackingModels_;

        //- Models for moving alpha by potential
        const moveAlphaByPotentialModelTable moveAlphaByPotentialModels_;

        //- Continuous phase models
        phaseSystem::phaseModelPartialList continuousPhaseModels_;


public:

    //- Runtime type information
    TypeName("resolvedInterfaceSystem");


    // Constructors

        //- Construct from a phase system
        resolvedInterfaceSystem(const phaseSystem&);


    //- Destructor
    virtual ~resolvedInterfaceSystem();


    // Member Functions

        // Access

            //- Return the phaseSystem
            const phaseSystem& fluid() const
            {
                return fluid_;
            }

            //- Return the mesh
            const fvMesh& mesh() const
            {
                return fluid_.mesh();
            }

            //- Return the models for phases that are moving
            const phaseSystem::phaseModelPartialList& continuousPhases() const
            {
                return continuousPhaseModels_;
            }


        // Interface compression

            //- Add interface compression flux
            void addCompressionFlux
            (
                const phaseModel& phase,
                surfaceScalarField& alphaPhi
            ) const;

            //- Return the surface tension force
            tmp<surfaceScalarField> surfaceTension
            (
                const phaseModel& phase
            ) const;


        // Interface properties

            //- Indicator field of the proximity of a resolved phase interface
            //  Values are distributed from 0 (far) to 1 (near).
            tmp<volScalarField> interfaceIndicator
            (
                const phaseModel& phase
            ) const;

            //- Interface gradient between two phases
            tmp<volVectorField> gradAlpha
            (
                const volScalarField& alpha1,
                const volScalarField& alpha2
            ) const;

            //- Interface gradient flux between two phases
            tmp<surfaceScalarField> gradAlphaf
            (
                const volScalarField& alpha1,
                const volScalarField& alpha2
            ) const;

            //- Return the interface normal vector across the interface for
            //  phase interface
            tmp<volVectorField> gradAlphaI(const phaseInterfaceKey& key) const;

            //- Normal to interface between two phases
            tmp<volVectorField> nHat
            (
                const volScalarField& alpha1,
                const volScalarField& alpha2
            ) const;

            //- Normal to interface between two phases
            tmp<surfaceVectorField> nHatfv
            (
                const volScalarField& alpha1,
                const volScalarField& alpha2
            ) const;

            //- Normal to interface between two phases dotted with face areas
            tmp<surfaceScalarField> nHatf
            (
                const volScalarField& alpha1,
                const volScalarField& alpha2
            ) const;

            //- Return the relative velocity across the interface for phase
            //  interface
            tmp<volVectorField> UrI(const phaseInterfaceKey& key) const;

            //- Return the shear stress magnitude across interface for phase
            //  interface
            tmp<volScalarField> tauI(const phaseInterfaceKey& key) const;

            //- Return the interface curvature for phase interface
            tmp<volScalarField> K
            (
                const segregatedPhaseInterface& interface
            ) const;


        // Indicator functions

            //- Return the degree of under-resolution for phase
            tmp<volScalarField> underResolution(const phaseModel& phase) const;

            //- Return the degree of under-resolution for phase interface
            tmp<volScalarField> underResolution
            (
                const phaseInterfaceKey& key
            ) const;


        // Morphology properties

            //- Return the mixture density based on continuous phases only
            tmp<volScalarField> rhoContinuous() const;

            //- Return the total volume fraction of continuous phases
            tmp<volScalarField> sumAlphaContinuous() const;


        // Update of fields

            //- Cluster tracking
            virtual void solve();

            //- Correct
            void correct();


        //- Dummy write for regIOobject
        bool writeData(Ostream& os) const;
};


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

} // End namespace Foam

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

#endif

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