CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (http://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Use LES filter operation (http://www.cfd-online.com/Forums/openfoam-programming-development/130398-use-les-filter-operation.html)

openfoammaofnepo February 25, 2014 09:33

Use LES filter operation
 
Dear all,

Similar to the filtering operation in dynamic Smagorinsky model for the incompressible flows:

Code:

homogeneousDynSmagorinsky.H
I am trying to use the same filtering operations in one of the applications, like rhoPimepleFoam. In order to see how the filtering is applied, I first read the code of homogeneousDynSmagorinsky, but I have two questions:

1, How the class LESfilter is initialized? In homogeneousDynSmagorinsky.H, it appears as the priviate data:

Code:

LESfilter& filter_
I think filter is initialized when homogeneousDynSmagorinsky is initilized but I did not find where the latter is initialzied.

2, In homogeneousDynSmagorinsky.C, the filter operation is applied as filter_(x), I do not why here filter_(*) is used like a function, it is an object!

Thank you so much if anyone can provide some guidance.

wyldckat March 1, 2014 07:15

Hi OFFO (the acronym OF is a lot easier to write ;)),

If the questions were about hard-core LES mathematics, I wouldn't be able to answer, but since it's C++ related questions, here we go:
Quote:

Originally Posted by openfoammaofnepo (Post 476706)
1, How the class LESfilter is initialized? In homogeneousDynSmagorinsky.H, it appears as the priviate data:

Code:

LESfilter& filter_
I think filter is initialized when homogeneousDynSmagorinsky is initilized but I did not find where the latter is initialzied.

This is a two sided issue:
Let's look at the C file: https://github.com/OpenFOAM/OpenFOAM...nSmagorinsky.C
  1. Looking at the constructor:
    Code:

    homogeneousDynSmagorinsky::homogeneousDynSmagorinsky
    (
        const volVectorField& U,
        const surfaceScalarField& phi,
        transportModel& transport,
        const word& turbulenceModelName,
        const word& modelName
    )

  2. You'll see this:
    Code:

    filterPtr_(LESfilter::New(U.mesh(), coeffDict())),
    filter_(filterPtr_())

    The first line initializes "filterPtr_" with a new "LESfilter". The second line will assign to the reference variable "filter_" the memory address pointed to by "filterPtr_", because "filterPtr_()" is using an operator. For more on this, have a look into this article: http://openfoamwiki.net/index.php/OpenFOAM_guide/tmp
Note: "autoPtr" is a much more simple class than "tmp", but they are conceptually similar.

Quote:

Originally Posted by openfoammaofnepo (Post 476706)
2, In homogeneousDynSmagorinsky.C, the filter operation is applied as filter_(x), I do not why here filter_(*) is used like a function, it is an object!

Already hinted in the previous answer, because in C++ we can override operators, as explained here: http://www.cplusplus.com/doc/tutorial/operators/
If you look into the header file respective to LESfilter: https://github.com/OpenFOAM/OpenFOAM...er/LESfilter.H - you'll see that there are four "operator()", each one receiving a different type of field. These are abstract virtual methods, as explained here: http://www.cplusplus.com/doc/tutorial/polymorphism/ - which means that you will have to look at the specific filter implementation to see what the respective operator does.

Best regards,
Bruno

openfoammaofnepo March 1, 2014 07:30

Dear Bruno,

Thank you first for your so detailed help. I will dig into it later today. Now I am implementing a dynamic constants in my mixing model, where the test filtering is used. Thank you again.

OFFO.

openfoammaofnepo March 5, 2014 12:16

Dear Bruno,

About the following lines:

Code:

filterPtr_(LESfilter::New(U.mesh(), coeffDict())),
filter_(filterPtr_())

You have already given me the explanations. Thank you. So actually filterPtr_ is the pointer toward the object of LESfilter and the latter is initilized by LESfilter::New(U.mesh(), coeffDict()). The correpsonding constructor is as follows:
Code:

        //- Return a reference to the selected LES filter
        static autoPtr<LESfilter> New
        (
            const fvMesh&,
            const dictionary&
        );

The operation filterPtr_() gives me the object that filterPtr_ points to.

Besides, filter_ is the reference of the object "filterPtr_()". Are the above what I saying correct?

In the dynamic LES models , the expressions filter_ extensively appears, like filter_(U()) and filter_(D). what is the relation between the filter_(U()) and filter_(filterPtr_())? A little confused.

Thank you so much.

OFFO

wyldckat March 5, 2014 16:38

Hi OFFO,

I know, C++ can get seriously confusing :( I suggest that you give a good study at this tutorial: http://www.cplusplus.com/doc/tutorial/

So, the notion to keep in mind is that this:
Code:

filterPtr_(LESfilter::New(U.mesh(), coeffDict())),
filter_(filterPtr_())

was declared in the initialization section of the constructor. This means that it follows the paradigm that the constructor will also initialize any dependant constructors of its child variables or inherited classes. Which is why the parenthesis are used.
In practice, for example, doing this:
Code:

MyOwnClass::MyOwnClass() :
  filterPtr_(LESfilter::New(U.mesh(), coeffDict())),
  filter_(filterPtr_())
{
}

Is almost the same thing as doing this:
Code:

MyOwnClass::MyOwnClass()
{
  filterPtr_ = LESfilter::New(U.mesh(), coeffDict());
  filter_ = filterPtr_();
}

The difference is usually a matter of performance, where the first one is more efficient and faster to do when the solver is running.
  • Side note - This:
    Code:

    filterPtr_ = LESfilter::New(U.mesh(), coeffDict());
    Is basically this:
    Code:

    filterPtr_ = new LESfilter(U.mesh(), coeffDict());
    But the difference is that we have to use the "New" method, because of some special operations that are needed when creating an instance of "LESfilter".


As for:
Code:

filter_(U);
is the same as doing this:
Code:

filter_.operator()(U);
where the method "operator()" is a special method, which is automatically called if you simply do the first form:
Code:

filter_(U);
And it's only possible to do so, because it was defined that way.
For example, doing:
Code:

filter_(2.0+1);
won't work, because the method "operator()(scalar value)" was not defined.

Best regards,
Bruno

openfoammaofnepo March 6, 2014 06:08

Dear Bruno,

Thank you for your help. Much clearer now!

have a nice day!

OFFO

ehsankf April 8, 2014 05:24

filter_
 
Hi Bruno,

I there a way to use filter_ operator in a solver like channelFoam, as in can be used in models.

wyldckat April 13, 2014 15:28

Quote:

Originally Posted by ehsankf (Post 484591)
I there a way to use filter_ operator in a solver like channelFoam, as in can be used in models.

Quick answer:
From what I can see, my guess is that you'll have to create a new local instance of LESfilter, indicated in point #2, at post #2, namely this one:
Quote:

Originally Posted by wyldckat (Post 477400)
2. You'll see this:
Code:

filterPtr_(LESfilter::New(U.mesh(), coeffDict())),
filter_(filterPtr_())



openfoammaofnepo April 13, 2014 15:36

Yes, Bruno is right.

In order to use coeffDict(), you need to define the following in createFields.H

Code:

    autoPtr<compressible::LESModel> les
    (
        compressible::LESModel::New
        (
            rho,
            U,
            phi,
            thermo
        )
    );

Then the lines mentioned in Bruno's thread is:

Code:

    autoPtr<LESfilter> filterPtr(LESfilter::New(U.mesh(), les->coeffDict()));
    LESfilter& filter(filterPtr());

Quote:

Originally Posted by wyldckat (Post 485841)
Quick answer:
From what I can see, my guess is that you'll have to create a new local instance of LESfilter, indicated in point #2, at post #2, namely this one:



All times are GMT -4. The time now is 00:17.