CFD Online Discussion Forums

CFD Online Discussion Forums (
-   OpenFOAM (
-   -   tmp<volScalarField> (

JBUNSW November 21, 2012 01:08

Hi there,

I have a general question regarding the concept of tmp<volScalarField>. To explain my question I use rho, as an example, from a combustion class in OF.

How can one calculate density?
The density can be accessed by invoking the rho() function which is a virtual function in basicPsiThermo class. So for example if thermo object has been setup correctly in a given class (such as ODEChemistryModel), then you can easily calculate density by equation of state of an ideal gas (there are other models available as well) by

which returns a tmp<volScalarField> accordingly:

virtual tmp<volScalarField> rho() const
        return p_*psi();

I was wondering what is the difference between the following four methods to access a tmp<volScalarField> quantity such as density (or any other tmp<volScalarField>).

Method 1:

const volScalarField& rho = this->db().objectRegistry::lookupObject<volScalarField>("rho");
Method 2:

tmp<volScalarField> trho = this->thermo().rho();
const volScalarField& rho = trho();

Method 3:

const volScalarField rho

Method 4:

const volScalarField rho = this->thermo().rho();

My question:
My understanding of the above is that method 1 is accessing the rho variable already stored in the objectRegistry and doesn't use the result of the virtual function rho(). The other methods all use the thermo().rho() function to calculate rho. In method 1 we do not create a "local" volScalarField variable and just use "referencing" to reference to some memory location. But in other 3 methods we are creating a "local" volScalarField variable and store the results in it.

1. Am I right?!
2. Why we use tmp<volScalarField> at all?!
3. Are all the above four methods correct?!
4. What is the difference between them?!

Thanks for your time,

olesen November 21, 2012 06:10

As far as I know, you are right on most of your points.
I may not be entirely correct myself, but here's my take on it (below).

The explanation only make sense if you are clear about the purpose of the tmp class. The tmp class is intended as means to free memory ASAP. The memory occupied by the tmp is released after the tmp has been involved in an operation. In contrast, a normal field is only released after it has gone out of scope (or been explicitly cleared via its clear method).

Thus if you wish to use a tmp field for several operations, you need to use the const reference to its field - this is the () method - to avoid destroying it after the first operation.

Method 1
Lookup an object in the registry. This is obviously incorrect for a tmp field.

Method 2:
Construct a tmp field and then use the () operator to obtain a const reference to the underlying field. The const reference can be used in many places.

Method 3
Construct an volume field and initialize it with the values taken from the tmp field. The memory associated with the tmp field will be reclaimed and used by the volume field. Your choice if you want this volume field to be read-only (ie, const) or read/write.

Method 4
Similar to the method 3, but probably better to use this form

const volScalarField rho(this->thermo().rho());
I think this makes clang happier. Again you can decorate this with/without the const, depending if the field is read-only or read/write.


ngj November 21, 2012 06:58

Furthermore, there is a good discussion on the tmp<> in the following thread:

Or here on the wiki:

Kind regards,


JBUNSW November 21, 2012 19:37

Thanks a bunch!
Dear Mark and Niles,

Thanks for your excellent comments. Enlightened me a lot...:)

As for method 1 above, I meant to lookup an actual field that is created in the solver scope (in createFields.H) not a tmp wrapper version of it. But good to know that lookup can't work on tmp fields.

My sincere regards,

All times are GMT -4. The time now is 04:41.