CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM

tmp<volScalarField>

Register Blogs Community New Posts Updated Threads Search

Like Tree18Likes
  • 7 Post By JBUNSW
  • 6 Post By olesen
  • 3 Post By ngj
  • 2 Post By JBUNSW

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   November 21, 2012, 01:08
Default tmp<volScalarField>
  #1
New Member
 
James Behzadi
Join Date: Oct 2011
Location: Sydney, Australia
Posts: 27
Rep Power: 15
JBUNSW is on a distinguished road
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
Code:
this->thermo().rho()
which returns a tmp<volScalarField> accordingly:
Code:
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:
Code:
const volScalarField& rho = this->db().objectRegistry::lookupObject<volScalarField>("rho");
Method 2:
Code:
tmp<volScalarField> trho = this->thermo().rho();
const volScalarField& rho = trho();

Method 3:
Code:
const volScalarField rho
(
	IOobject
	(
		"rho",
		this->time().timeName(),
		this->mesh(),
		IOobject::NO_READ,
		IOobject::NO_WRITE,
		false
	),
	this->thermo().rho()
);

Method 4:
Code:
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,
Jalal
JBUNSW is offline   Reply With Quote

Old   November 21, 2012, 06:10
Default
  #2
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,714
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
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
Code:
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.

/mark
olesen is offline   Reply With Quote

Old   November 21, 2012, 06:58
Default
  #3
ngj
Senior Member
 
Niels Gjoel Jacobsen
Join Date: Mar 2009
Location: Copenhagen, Denmark
Posts: 1,902
Rep Power: 37
ngj will become famous soon enoughngj will become famous soon enough
Furthermore, there is a good discussion on the tmp<> in the following thread:

http://www.cfd-online.com/Forums/ope...acro-pain.html

Or here on the wiki:

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

Kind regards,

Niels
Tobi, Zhiheng Wang and lpz456 like this.
ngj is offline   Reply With Quote

Old   November 21, 2012, 19:37
Default Thanks a bunch!
  #4
New Member
 
James Behzadi
Join Date: Oct 2011
Location: Sydney, Australia
Posts: 27
Rep Power: 15
JBUNSW is on a distinguished road
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,
Jalal
Zhiheng Wang and lpz456 like this.
JBUNSW is offline   Reply With Quote

Reply

Tags
objectregistry, referencing, tmp<volscalarfield>


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On



All times are GMT -4. The time now is 02:37.