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

Description
    Base class for under-resolution models.

    According to Coste (2013), the interfacial shear stress is approximated by
    considering coupled wall laws at both sides of the interface. If required,
    the interfacial roughness on the gas-side of the interface is taken into
    account.

    Reference:
    \verbatim
        Coste, P. (2013).
        A Large Interface Model for two-phase CFD.
        Nuclear Engineering and Design, 255, 38–50.
    \endverbatim

Usage
    \table
        Property| Description                        | Required| Default value
        interfaceRoughness| whether to consider rough interfaces | no | no
        nCorrectors | number of corrector loops for shear stress | no | 3
        nLayers | maximum number of interfacial cells            | no | 5
    \endtable

See also
    Foam::ResolvedPhaseSystem

SourceFiles
    underResolutionModel.C
    underResolutionModelNew.C

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

#ifndef underResolutionModel_H
#define underResolutionModel_H

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

#include "volFields.H"
#include "dictionary.H"
#include "runTimeSelectionTables.H"
#include "segregatedPhaseInterface.H"

namespace Foam
{

/*---------------------------------------------------------------------------*\
                    Class underResolutionModel Declaration
\*---------------------------------------------------------------------------*/

class underResolutionModel
:
    public regIOobject
{
    // Private Data

        //- Gas phase
        const phaseModel& lightPhase_;

        //- Liquid phase
        const phaseModel& heavyPhase_;

        //- Switch for considering interface roughness
        const Switch interfaceRoughness_;

        //- Number of corrector loops for interfacial shear stress
        const label nCorrectors_;


    // Model Constants

        // Threshold parameter for log law for smooth walls
        const scalar Cs_;

        // Offset parameter of log law for smooth walls
        const scalar Bs_;

        // Karman constant
        const scalar kappa_;

        // Threshold Reynolds number between smooth and rough interfaces
        const scalar RerS_;

        // Threshold Reynolds number for rough wall law
        const scalar RerR_;

        // Offset Parameter of log law for rough walls
        const scalar Br_;

        // Charnock parameter
        const scalar beta1_;

        // Threshold parameter for wave height
        const scalar beta2_;

        // Upper limit model parameter for turbulence roughness
        const scalar q310_;

        // Lower limit model parameter for turbulence roughness
        const scalar q320_;

        // Safety margin to regime boundary for blob size calculation
        const scalar DeltaMu_;


    // Interface Data

        //- Interface normal vector across the interface
        volVectorField gradAlphaI_;

        //- Estimated distance from interface (alpha = 0.5)
        //  Zero at interface, positive towards phase 1,
        //  negative towards phase2
        volScalarField yI_;

        //- Estimated velocity at phase 1
        volVectorField U1I_;

        //- Estimated velocity at phase 2
        volVectorField U2I_;

        //- Relative velocity across the interface
        volVectorField UrI_;

        //- Absolute estimated velocity at interface
        volVectorField UI_;

        //- Shear stress magnitude across interface
        volScalarField tauI_;

        //- Interface roughness
        volScalarField roughness_;


    // Private Member Functions

        //- Estimated interface thickness
        virtual tmp<volScalarField> DeltaI() const;

        //- Upper limit of transition region (3.1)
        tmp<volScalarField> Q31
        (
            const volScalarField& Lb,
            const volScalarField& gn
        ) const;

        //- Lower limit of transition region (3.2)
        tmp<volScalarField> Q32
        (
            const volScalarField& Lb,
            const volScalarField& gn
        ) const;

        //- Blob size
        tmp<volScalarField> blobSize
        (
            const volScalarField& q,
            const volScalarField& gn
        ) const;

        //- Estimated interface roughness (4.12)
        tmp<volScalarField> roughness
        (
            const volScalarField& yGI,
            const volScalarField& uStarG
        ) const;

        //- Viscous part of law of the wall, returns uStar
        tmp<volScalarField> wallLawViscous
        (
            const volScalarField& yI,
            const volScalarField& deltaU,
            const volScalarField& nu
        ) const;

        //- Law of the wall for smooth walls, returns uStar
        tmp<volScalarField> wallLawSmooth
        (
            const volScalarField& yPlus,
            const volScalarField& yI,
            const volScalarField& deltaU,
            const volScalarField& nu
        ) const;

        //- Law of the wall for rough walls, returns uStar
        tmp<volScalarField> wallLawRough
        (
            const volScalarField& yPlus,
            const volScalarField& yI,
            const volScalarField& deltaU,
            const volScalarField& nu,
            const volScalarField& Rer
        ) const;

        //- Law of the wall for walls, returns uStar
        tmp<volScalarField> wallLaw
        (
            const volScalarField& yPlus,
            const volScalarField& yI,
            const volScalarField& deltaU,
            const volScalarField& nu,
            const volScalarField& Rer
        ) const;

        //- Mean shear stress, corrects individual uStars
        tmp<volScalarField> tau
        (
            volScalarField& uStar1,
            volScalarField& uStar2,
            const volScalarField rho1,
            const volScalarField rho2
        ) const;

        //- Correct interface normal vector across the interface
        void correctGradAlphaI();

        //- Correct velocities across the interface and distance to interface
        void correctUIyI();

        //- Correct shear stress magnitude across interface
        void correctTauI();


protected:

    // Protected Data

        //- Phase interface
        const segregatedPhaseInterface interface_;

        //- Reference to the mesh
        const fvMesh& mesh_;

        //- Degree of under resolution
        volScalarField underResolution_;

        //- Number of layers to consider across the interface
        const label nLayers_;


    // Protected Member Functions

        //- Primitive smoothing procedure for arbitrary field
        template<class fieldType>
        void smoothen
        (
            fieldType& field,
            const label nLayers = 2
        ) const;


public:

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


    // Declare runtime construction

        declareRunTimeSelectionTable
        (
            autoPtr,
            underResolutionModel,
            dictionary,
            (
                const dictionary& dict,
                const phaseInterface& interface,
                const bool registerObject
            ),
            (dict, interface, registerObject)
        );

    // Constructors

        //- Construct from a dictionary and an interface
        underResolutionModel
        (
            const dictionary& dict,
            const phaseInterface& interface,
            const bool registerObject
        );


    //- Destructor
    virtual ~underResolutionModel();


    // Selectors

        static autoPtr<underResolutionModel> New
        (
            const dictionary& dict,
            const phaseInterface& interface,
            const bool outer=true,
            const bool registerObject=true
        );


    // Member Functions

        // Access

            //- Return reference to interface normal vector across the interface
            inline const volVectorField& gradAlphaI() const
            {
                return gradAlphaI_;
            }

            //- Return reference to relative velocity across the interface
            inline const volVectorField& UrI() const
            {
                return UrI_;
            }

            //- Return reference to shear stress magnitude across interface
            inline const volScalarField& tauI() const
            {
                return tauI_;
            }

            //- Return reference to interface roughness
            inline const volScalarField& roughness() const
            {
                return roughness_;
            }

            //- Return reference to degree of under resolution
            inline const volScalarField& underResolution() const
            {
                return underResolution_;
            }


        //- Return the wall distance, creating and storing it if necessary
        const volScalarField& yWall() const;

        //- Correct under resolution factor
        virtual void correct();

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


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

} // End namespace Foam

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

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

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

#endif

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