/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                 |
| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \\    /   O peration     | Version:  v1812                                 |
|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
|    \\/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    system;
    object      preProcess;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

functions
{
    createVortex
    {
        name    createVortices;
        type    coded;
        libs    ("libutilityFunctionObjects.so");
        enabled yes;

        codeInclude
        #{
            #include "volFields.H"
        #};

        codeWrite
        #{
            scalar D = 0.57;
            scalar UInf = 50;
            scalar pInf = 101325;
            scalar TInf = 224;
            scalar gamma = 1.4;
            scalar A = -0.3*D*UInf;
            const dimensionedScalar rhoRef("rhoRef", dimDensity, 1);
            const auto& rho = mesh().lookupObject<volScalarField>("rho");

            const vectorField& C = mesh().C();
            const scalarField x(C.component(0));
            const scalarField y(C.component(1));
            const scalar r2 = sqr(0.5*D/(Foam::sqrt(Foam::log(10.0))));
            const scalarField Psi(A*exp(-0.5/r2*(sqr(x) + sqr(y))));

            auto* Uptr = mesh().getObjectPtr<volVectorField>("U");
            auto* pPtr = mesh().getObjectPtr<volScalarField>("p");
            auto* TPtr = mesh().getObjectPtr<volScalarField>("T");

            if (Uptr && pPtr && TPtr)
            {
                auto& U = *Uptr;
                auto& p = *pPtr;
                auto& T = *TPtr;

                vectorField& Uc = U.primitiveFieldRef();
                Uc.replace(0, UInf - rhoRef/rho()*Psi/r2*y);
                Uc.replace(1, rhoRef/rho()*Psi/r2*x);
                U.correctBoundaryConditions();
                U.write();

                scalarField& pc = p.primitiveFieldRef();
                pc = pInf - 0.5*sqr(rhoRef)/rho()*sqr(Psi)/r2;
                p.correctBoundaryConditions();
                p.write();

                scalarField& Tc = T.primitiveFieldRef();
                Tc = pow(pc/pInf, (gamma - 1)/gamma)*TInf;
                T.correctBoundaryConditions();
                T.write();
            }
            else
            {
                FatalErrorInFunction
                    << "Unable to find pressure, velocity and temperature"
                    << " fields" << exit(FatalError);
            }
        #};
    }
}


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