CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Make wall-function read a newly defined field inside modified kEpsilon model (https://www.cfd-online.com/Forums/openfoam-programming-development/189858-make-wall-function-read-newly-defined-field-inside-modified-kepsilon-model.html)

Radunz June 28, 2017 23:29

Make wall-function read a newly defined field inside modified kEpsilon model
 
1 Attachment(s)
Greetings everyone,

I have been working on a modified kEpsilon model for wind flow modeling and it was necessary to redefine the once constant Cmu and as height-dependent field i.e. a volScalarField. I have also created it as an IObject to plot it along with the remaining fields and all works fine. The problems begin now. It just so happens that epsilonWallFunction and nutkRoughWallFunction depend on Cmu and as such the must access the modified kEpsilon height-dependent Cmu, which I will name after Cmu(z). I am well aware that the wall functions are general and thus have no information about the selected turbulence model so they access turbulence fields through their base class turbulenceModel.H through this lines, as example (turbulence kinectic energy, viscosity and turbulent viscosity fields):

@epsilonWallFunction

const tmp<volScalarField> tk = turbulence.k();
const volScalarField& k = tk();

const tmp<scalarField> tnuw = turbulence.nu(patchi);
const scalarField& nuw = tnuw();

const tmp<scalarField> tnutw = turbulence.nut(patchi);
const scalarField& nutw = tnutw();

However, when I try to access the newly created Cmu(z) through this

const tmp<volScalarField> tCmuw = turbulence.CmuZ();


The compiler complains saying basically that "error: ‘const class Foam::turbulenceModel’ has no member named ‘CmuZ’". This is attached as "log.withoutTurbulenceModel". So what have I done? I realized the call above led to the base class turbulenceModel so I declared CmuZ as a virtual function there.

@turbulenceModel.H

virtual tmp<volScalarField> CmuZ() const = 0;

When I compile, I get more issues. In my view, the issue is that somehow turbulenceModel's derived classes (turbulence models) are scanned after the CmuZ() field which is only implemented in kEpsilon model through run-time selection tables. There are some lines as

"error: cannot allocate an object of abstract type ‘Foam::incompressible::RASModels::qZeta’
return autoPtr<baseType>(new baseType##Type parList); \
^
../turbulenceModels/lnInclude/RASModel.H:111:9: note: in expansion of macro ‘declareRunTimeSelectionTable’"

and that's when I get lost. I've been trying so solve this for two weeks, read about polymorphism and so on but stagnated.

Best regards.

usv001 July 1, 2017 00:54

Hi there,

You are correct that the "cannot allocate an object of abstract type" error occurs because you are trying to a create an object which has a pure virtual function, i.e. one which ends with '= 0'. I think that means that each of the derived class is required to provide an implementation of the CmuZ() which is not what you want to do.

Try writing the function body of the CmuZ() function in turbulenceModel.H to return a tmp<volScalarField> with the some dummy Cmu value like 0.09.

Code:

tmp<volScalarField> CmuZ()
{
    return
    (
        new volScalarField
        (
            volScalarField
            (
                IOobject("Cmu", ...),
                mesh,
                dimensionedScalar("dummy", dimless, 0.09)
            )
        )
    );
}

Then, you may specialize this function in your own custom turbulence model. Now, you should be able to access this function from the wall function classes. I am not sure if this will work for certain but please give it a try and let everyone know of the result.

An even more straightforward way could be to access the Cmu volScalarField by looking up the object from its object registry, e.g.

Code:

const volScalarField& Cmu = mesh.lookupObject<volScalarField>("Cmu");
Cheers,
USV

Radunz July 18, 2017 22:39

Quote:

Originally Posted by usv001 (Post 655473)
Hi there,

You are correct that the "cannot allocate an object of abstract type" error occurs because you are trying to a create an object which has a pure virtual function, i.e. one which ends with '= 0'. I think that means that each of the derived class is required to provide an implementation of the CmuZ() which is not what you want to do.

Try writing the function body of the CmuZ() function in turbulenceModel.H to return a tmp<volScalarField> with the some dummy Cmu value like 0.09.

Code:

tmp<volScalarField> CmuZ()
{
    return
    (
        new volScalarField
        (
            volScalarField
            (
                IOobject("Cmu", ...),
                mesh,
                dimensionedScalar("dummy", dimless, 0.09)
            )
        )
    );
}

Then, you may specialize this function in your own custom turbulence model. Now, you should be able to access this function from the wall function classes. I am not sure if this will work for certain but please give it a try and let everyone know of the result.

An even more straightforward way could be to access the Cmu volScalarField by looking up the object from its object registry, e.g.

Code:

const volScalarField& Cmu = mesh.lookupObject<volScalarField>("Cmu");
Cheers,
USV

Thank you very much. The piece of code
Code:

const volScalarField& Cmu = mesh.lookupObject<volScalarField>("Cmu");
indeed solved my problems.


All times are GMT -4. The time now is 05:10.