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

Description
    Control inlet velocity based on a registered dimensioned vector quantity,
    such as a deviation from a target centre of gravity of a gas structure.

Usage
    \table
        Property        | Description                 | Required| Default value
        controlVar      | Name of control variable    | yes     | -
        targetPos       | Target position             | yes     | -
        kP              | Proportional PID coefficient| no      | (0, 0, 0)
        kI              | Integral PID coefficient    | no      | (0, 0, 0)
        kD              | Differential PID coefficient| no      | (0, 0, 0)
        relaxationFactor| relaxation factor for deviation| no   | 1.0
    \endtable

    Example of the boundary condition specification:
    \verbatim
    <patchName>
    {
        type                PIDcontrolledInletVelocity;

        libs                ("libaddonFiniteVolume.so");

        controlVar          CG.alpha.air;
        targetPos           (0 0 1);

        kP                  (0 0 -0.8 );
        kI                  (0 0 -0.05);
        kD                  (0 0 -0.2 );

        relaxationFactor    0.8;
    }
    \endverbatim

SourceFiles
    PIDcontrolledInletVelocityFvPatchVectorField.C

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

#ifndef PIDcontrolledInletVelocityFvPatchVectorField_H
#define PIDcontrolledInletVelocityFvPatchVectorField_H

#include "fixedValueFvPatchFields.H"
#include "dimensionedTypes.H"

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

namespace Foam
{

/*---------------------------------------------------------------------------*\
        Class PIDcontrolledInletVelocityFvPatchVectorField Declaration
\*---------------------------------------------------------------------------*/

class PIDcontrolledInletVelocityFvPatchVectorField
:
    public fixedValueFvPatchVectorField
{
    // Private Data

        //- Control variable
        const word controlVarName_;

        //- Target position
        const dimensionedVector targetPos_;

        //- Proportional coefficient
        const dimensionedVector kP_;

        //- Integral coefficient
        const dimensionedVector kI_;

        //- Differential coefficient
        const dimensionedVector kD_;

        //- Factor for under-relaxation of control variable
        const scalar relaxationFactor_;

        //- Recent value of deviation, required for smooth restart
        dimensionedVector deviation_;

        //- Last time step value of deviation, required for smooth restart
        dimensionedVector deviation0_;

        //- Time level or recent value of control variable
        label timeIndex0_;

        //- Integral of controlled variable, required for smooth restart
        dimensionedVector uI_;


public:

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


    // Constructors

        //- Construct from patch, internal field and dictionary
        PIDcontrolledInletVelocityFvPatchVectorField
        (
            const fvPatch&,
            const DimensionedField<vector, volMesh>&,
            const dictionary&
        );

        //- Construct by mapping given PIDcontrolledInletVelocity onto a new
        //  patch
        PIDcontrolledInletVelocityFvPatchVectorField
        (
            const PIDcontrolledInletVelocityFvPatchVectorField&,
            const fvPatch&,
            const DimensionedField<vector, volMesh>&,
            const fieldMapper&
        );

        //- Disallow copy without setting internal field reference
        PIDcontrolledInletVelocityFvPatchVectorField
        (
            const PIDcontrolledInletVelocityFvPatchVectorField&
        ) = delete;

        //- Copy constructor setting internal field reference
        PIDcontrolledInletVelocityFvPatchVectorField
        (
            const PIDcontrolledInletVelocityFvPatchVectorField&,
            const DimensionedField<vector, volMesh>&
        );

        //- Construct and return a clone setting internal field reference
        virtual tmp<fvPatchVectorField> clone
        (
            const DimensionedField<vector, volMesh>& iF
        ) const
        {
            return tmp<fvPatchVectorField>
            (
                new PIDcontrolledInletVelocityFvPatchVectorField(*this, iF)
            );
        }


    // Member Functions

        // Evaluation functions

            //- Update the coefficients associated with the patch field
            virtual void updateCoeffs();


        //- Write
        virtual void write(Ostream&) const;
};


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

} // End namespace Foam

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

#endif

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