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/)
-   -   What is does the "()" operator do in "turbulence->k() ()"? (https://www.cfd-online.com/Forums/openfoam-programming-development/188176-what-does-operator-do-turbulence-k.html)

MakisH May 24, 2017 13:42

What does the "()" operator do in "turbulence->k() ()"?
 
I am trying to understand what the purpose of the "()" operator is. What is the difference between
Code:

turbulence->k() ()
and
Code:

turbulence->k()
?

In this case, "turbulence" is declared as
Code:

autoPtr<compressible::turbulenceModel> & turbulence
Is it OpenFOAM-specific or does it come from C++?
Is it related to "const"? Would this return a "const" or a "non-const"? How can I get the same thing without "const"?
Is it different in OpenFOAM v.4 compared to v.3? (maybe related to this commit).

Any hints would be useful, because I don't know how and where to search for this kind of operator.

Edit: I still don't know what it does, but it looks like it works in OpenFOAM 4.1 if I write:
Code:

turbulence->k().ref()
I don't know what exactly I did though...

TomasDenk May 25, 2017 11:03

I think it is dereference operator. You can check tmp class for details:

Code:

//- Const dereference operator
inline const T& operator()() const;

If you want to assign refValue using temporary scalar field you need to do this:
Code:

tmp<scalarField> myFld(new scalarField(SIZE, VALUE));
refValue() = myFld();

or you can do something like this:
Code:

scalarField myFld = patch.lookupPatchField<volScalarField, scalar> (NAME);
refValue() = myFld;


MakisH May 26, 2017 08:05

Thank you very much TomasDenk! I am still a bit confused about the purpose of the operator.

However, I found this useful note in the release notes of OpenFOAM 4:
Quote:

Robust data handling: new convention for const and non-const reference functions of fields where the non-const function uses …Ref(); for example, where boundaryField() provides the const reference to the boundary field, boundaryFieldRef() provides a non-const reference. » more »; for tmp objects, non-const access uses a ref() function rather than the () dereferencing operator. » more »
From this (and from your answer) I understand that:
  1. It is a dereferencing operator.
  2. It is related to tmp objects.
  3. In OpenFOAM 4, the "()" returns a const, while the ".ref()" returns a non-const.

TomasDenk May 30, 2017 08:38

You understood well the note that you quote and the points 1 through 3 are correct. As for the purpose of the "()" operator - it gives you access to the actual field wrapped in tmp<> template class. And as you mention, you can use .ref() to access non-const field.
<P>Why would you use tmp<> class? It is customary to wrap temporary fields in tmp<> to make sure that the memory is released properly. However, I'm not solid C++ programmer and someone with deepr insight could provide you with more detailed answer.

akidess May 30, 2017 09:58

https://openfoamwiki.net/index.php/OpenFOAM_guide/tmp

MakisH June 1, 2017 06:33

Thank you both for the help!

I have another question on this: what would happen if I did not use this operator? I think this would really help me understanding. I.e. what is the difference between the two lines in my first post (for OpenFOAM version < 4)?

Code:

turbulence->k() ()

vs

turbulence->k()

Assume two scenarios:
1. Using these in an inline computation or printing.
2. Using these as arguments to call a method.

@TomasDenk: From what I read on OpenFOAM Wiki, I think the most important reason to use the tmp<> is to avoid copying large data around whenever a function is called. But of course the "proper release of memory" is also important.

TomasDenk June 13, 2017 09:32

Sorry for my late reply, I was very busy while traveling.

Suppose you want to use such field wrapped in tmp class for setting BC. I think you can use the wrapper object without harm:

Code:

tmp<scalarField> fld(new scalarField(fldSize, anyValue));
// do some field operations
refValue() = fld;

This compiles just fine. However, if you need to access the field face-by-face, you would get compilation error with such code:

Code:

forAll(*this, faceI)
{
    refValue()[faceI] = someFunction(fld[faceI]);
}

Dereference operator saves the day:

Code:

forAll(*this, faceI)
{
    refValue()[faceI] = someFunction(fld()[faceI]);
}

Hope this help.


All times are GMT -4. The time now is 23:48.