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/)
-   -   Modifying solver for LES simulation (https://www.cfd-online.com/Forums/openfoam-programming-development/158085-modifying-solver-les-simulation.html)

syavash August 14, 2015 14:41

Modifying solver for LES simulation
 
Dear Foamers,

I am trying to modify pimpleFoam to include SGS Reynolds stress as this thread has pointed out:

http://www.cfd-online.com/Forums/ope...n-etc-les.html
posts #15, #16, and #17.

For this aim, I have created a Tensor field in "createFields.H" as follows:

Code:

volSymmTensorField B
(
IOobject
(
"B",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
mesh
);


Then, I have added the following line to my new modified solver, "MypimpleFoam.C" :

Code:

while (runTime.run())
{
....
....

B = dynamicSmagorinsky->B();

...
}

But when I try to compile the code, I get the following error:

Code:

Making dependency list for source file MypimpleFoam.C
SOURCE=MypimpleFoam.C ;  g++ -m64 -Dlinux64 -DWM_DP -Wall -Wextra -Wno-unused-parameter -Wold-style-cast -Wnon-virtual-dtor -O3  -DNoRepository -ftemplate-depth-100 -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/turbulenceModels/incompressible/turbulenceModel -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/turbulenceModels/incompressible/LES/dynamicSmagorinsky -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/transportModels -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/transportModels/incompressible/singlePhaseTransportModel -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/finiteVolume/lnInclude -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/meshTools/lnInclude -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/fvOptions/lnInclude -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/sampling/lnInclude -IlnInclude -I. -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OpenFOAM/lnInclude -I/home/syavash/OpenFOAM/OpenFOAM-2.3.1/src/OSspecific/POSIX/lnInclude  -fPIC -c $SOURCE -o Make/linux64GccDPOpt/MypimpleFoam.o
MypimpleFoam.C: In function ‘int main(int, char**)’:
MypimpleFoam.C:89:18: error: ‘dynamicSmagorinsky’ was not declared in this scope
              B = dynamicSmagorinsky->B();
                  ^
make: *** [Make/linux64GccDPOpt/MypimpleFoam.o] Error 1

I have seen people modified their solvers to include this but I cannot manage to resolve this problem.
Please help me to understand and solve this problem.

Thanks,
Syavash

alexeym August 14, 2015 15:52

Hi,

Why would you need to modify pimpleFoam to use LES? The solver is quite general so it can use LES turbulence models without any modifications, see for example tutorials/incompressible/pimpleFoam/channel395 case.

syavash August 14, 2015 18:07

Quote:

Originally Posted by alexeym (Post 559634)
Hi,

Why would you need to modify pimpleFoam to use LES? The solver is quite general so it can use LES turbulence models without any modifications, see for example tutorials/incompressible/pimpleFoam/channel395 case.

Hi Alexey,

Let me clarify myself: I need to modify the solver to include SGS Reynolds stresses and subsequently activating its averaging in controlDict to have an averaged SGS Reynolds stress field for post-processing.
As you know, by default, only the "resolved" Reynolds stresses are generated when averaging.
Can you help me do that?!

Syavash

alexeym August 15, 2015 08:35

Hi,

Still did not quite get what you are trying to achieve. All machinery for LES is already in code base. If you take a look at LESModel class:

Code:

class LESModel
:     
    public turbulenceModel,
    public IOdictionary
{
    ...
        //- Return the sub-grid stress tensor.
        virtual tmp<volSymmTensorField> B() const = 0;
    ...
            //- Return the Reynolds stress tensor
            virtual tmp<volSymmTensorField> R() const
            {
                return B();
            }
    ...
}

So your desire to call dynamicSmagorinsky->B() should be expressed as turbulence->R() (since turbulence is available in pimpleFoam, see createFields.H file). So if you set simulation type to LESModel in turbulenceProperties and then select model in LESProperties, call to turbulence->R() will trigger calculation of SGS Reynolds stress tensor.

At this point nuance appears, because there are two types of LES models. One type is a children of GenSGSStress class, which directly solve for the SGS stress tensor B, another is a children of GenEddyVisc class. While GenSGSStress class has B_ tensor field, which is recalculated and automatically saved, GenEddyVisc does not have this field, so even Reynolds stress tensor in these models is calculated, it is not automatically written.

So to save Reynolds stress tensor you can do something like:

1. Add this to createField.H

Code:

volSymmTensorField B
(
    IOobject
    (
        "B",
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    ),
    mesh
);

2. Add field update code in the solver after turbulence->correct() call

Code:

B = turbulence->R()
Though this implementation could create problems if you use GenSGSStress-type turbulence model. Maybe instead of B, you could use myLovelyB name instead.

Also instead of IOobject::MUST_READ, you can use IOobject::READ_IF_PRESENT flag in constructor, so you do not have to create B file in 0 folder. If this case instead of mesh in constructor you should use turbulence->R().

syavash August 16, 2015 06:28

Quote:

Originally Posted by alexeym (Post 559672)
Hi,

Still did not quite get what you are trying to achieve. All machinery for LES is already in code base. If you take a look at LESModel class:

Code:

class LESModel
:     
    public turbulenceModel,
    public IOdictionary
{
    ...
        //- Return the sub-grid stress tensor.
        virtual tmp<volSymmTensorField> B() const = 0;
    ...
            //- Return the Reynolds stress tensor
            virtual tmp<volSymmTensorField> R() const
            {
                return B();
            }
    ...
}

So your desire to call dynamicSmagorinsky->B() should be expressed as turbulence->R() (since turbulence is available in pimpleFoam, see createFields.H file). So if you set simulation type to LESModel in turbulenceProperties and then select model in LESProperties, call to turbulence->R() will trigger calculation of SGS Reynolds stress tensor.

At this point nuance appears, because there are two types of LES models. One type is a children of GenSGSStress class, which directly solve for the SGS stress tensor B, another is a children of GenEddyVisc class. While GenSGSStress class has B_ tensor field, which is recalculated and automatically saved, GenEddyVisc does not have this field, so even Reynolds stress tensor in these models is calculated, it is not automatically written.

So to save Reynolds stress tensor you can do something like:

1. Add this to createField.H

Code:

volSymmTensorField B
(
    IOobject
    (
        "B",
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ,
        IOobject::AUTO_WRITE
    ),
    mesh
);

2. Add field update code in the solver after turbulence->correct() call

Code:

B = turbulence->R()
Though this implementation could create problems if you use GenSGSStress-type turbulence model. Maybe instead of B, you could use myLovelyB name instead.

Also instead of IOobject::MUST_READ, you can use IOobject::READ_IF_PRESENT flag in constructor, so you do not have to create B file in 0 folder. If this case instead of mesh in constructor you should use turbulence->R().

Hi Alexey,

Thank you for your comprehensive explanation. So I should use turbulence->R() in any case, whether using a SGS model e.g. dynSmagorinsky model or a OneEqn model and put B = turbulence->R() immediately after turbulence->correct() in the solver(please correct me if I am wrong).

Quote:

since turbulence is available in pimpleFoam, see createFields.H file
I have already checked createFields.H but no turbulence fields is defined. I guess I should construct it manually.

Thanks,
Syavash

alexeym August 16, 2015 06:55

Hi,

Quote:

Originally Posted by syavash (Post 559717)
So I should use turbulence->R() in any case, whether using a SGS model e.g. dynSmagorinsky model or a OneEqn model and put B = turbulence->R() immediately after turbulence->correct() in the solver(please correct me if I am wrong).

Since both dynSmagorinsky and oneEqEddy are children of LESModel class, they have R method (for compatibility with RANS models, and this method just calls B method, which in turn calculates sub-grid street tensor).

Concerning second part of the question: in principle, yes. Though first you have to create B field in creareField.H file (or elsewhere in main function before time loop).

Quote:

I have already checked createFields.H but no turbulent fields is defined. I guess I should construct it manually.
Turbulence fields are defined inside turbulence model. And turbulence model is created in the end of createField.H file.

Also since you need this sub-grid scale stress during post-processing, you can use R utility to calculate stress tensor. Though since you are trying to use algebraic and one-equation models there could be certain problems with the field name.


All times are GMT -4. The time now is 12:15.