CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > OpenFOAM Running, Solving & CFD

Understanding tmp%2360T classes

Register Blogs Members List Search Today's Posts Mark Forums Read

Reply
 
LinkBack Thread Tools Display Modes
Old   July 4, 2008, 17:35
Default Hi! I would like to ask if yo
  #1
nadine
Guest
 
Posts: n/a
Hi!
I would like to ask if you can recommend a good explanation how the tmp<t> classes are supposed to be used.
As long as I copy parts of the source code from existing solvers, I have been more or less able to get rid of the bugs that I produced when trying to work with tmp<>. But I definitely don't understand what is going on in the temporaries, so that I receive lots of segfaults when I can't get along with copying code.

Am I right that each tmp<> can be only used in a single calculation and then the temporary is invalidated? What is the reasoning behind this implementation? And can I find some guidelines how to use temporaries successfully?

Thank you
Nadine
  Reply With Quote

Old   July 5, 2008, 14:21
Default A tmp<> object is used in the
  #2
Senior Member
 
Sandeep Menon
Join Date: Mar 2009
Location: Amherst, MA
Posts: 386
Rep Power: 15
deepsterblue will become famous soon enough
A tmp<> object is used in the safe and automatic allocation/deallocation of temporary objects (like Fields, volFields, etc). Each tmp<> object has a reference count which gets incremented at allocation and decremented when the destructor is called. When the refCount is zero and the destructor is called (usually in situations when the object is going out of scope), the pointer to the object is deleted.

tmp objects can be used any number of times, as long as it stays in scope. Hope this helps.
__________________
Sandeep Menon
University of Massachusetts Amherst
https://github.com/smenon
deepsterblue is offline   Reply With Quote

Old   July 5, 2008, 16:00
Default "Each tmp<> object has a refer
  #3
nadine
Guest
 
Posts: n/a
"Each tmp<> object has a reference count which gets incremented at allocation and decremented when the destructor is called."

How would this work?

If I allocate a tmp(A), there is one single reference to A, if I allocate another tmp(A), the count has to be incremented. But if I allocate a tmp(B), the refcount has to be one again.
Does the tmp<> template have a static list of all classes and objects which it has allocated?

Or do you mean that tmp is a replacement for the boost smart pointers (www.boost.org/doc/libs/release/libs/smart_ptr)?

Thank you
Nadine
  Reply With Quote

Old   July 6, 2008, 03:47
Default "Each tmp<> object has a refer
  #4
Senior Member
 
Martin Beaudoin
Join Date: Mar 2009
Posts: 330
Rep Power: 13
mbeaudoin will become famous soon enough
"Each tmp<> object has a reference count which gets incremented at allocation and decremented when the destructor is called."

The reference counter is not a global variable.

tmp(A) and tmp(B) are both distinct and separate objects, with both their internal refcount.

Martin
mbeaudoin is offline   Reply With Quote

Old   July 24, 2008, 05:13
Default Hi! After a few weeks I'm c
  #5
nadine
Guest
 
Posts: n/a
Hi!

After a few weeks I'm coming back to my question about how to use tmp<t> template classes. I show a small piece of code which doesn't behave as I expect. Can you point out, what I'm getting wrong?

Here is the file test.C:
>>>>>>>>>>>>>>>>>>>>>>>>
#include "fvCFD.H"

#include <iostream>
using namespace std;

class A{
int cnt;
public:
A(){cout<<"A::A()\n"; cnt=0;}
~A(){cout<<"A::~A()\n";}
bool okToDelete(){return true;}
void peek(){cout<<"A::peek() cnt="<<cnt<<"\n";}
int operator--(){cnt--; cout<<"A::op--() returns "<<cnt<<"\n"; return cnt;}
int operator++(){cnt++; cout<<"A::op++() returns "<<cnt<<"\n"; return cnt;}
};

int main(int argc, char *argv[])
{
//A *a=new A(); //this line instead of the next one causes a "double free or corruption"
A a;

tmp<a > t1(a);
t1().peek();
tmp<a > t2=t1;
t2().peek();
}
<<<<<<<<<<<<<<<<<<<<<

You can use this simple Makefile to build the executable "test" by running "make test" (assuming a linux OS):
>>>>>>>>>>>>>>>>>>>>>
CPPFLAGS=-DDP -DNoRepository \
-I$(FOAM_SRC)/OpenFOAM/lnInclude \
-I$(FOAM_SRC)/finiteVolume/lnInclude \
-I$(FOAM_APP)/solvers/incompressible/icoFoam
LDFLAGS=-L $(FOAM_LIB)/linuxGccDPOpt
LDLIBS=-lOpenFOAM
<<<<<<<<<<<<<<<<<<<<<

The output from running "./test" is:
>>>>>>>>>>>>>>>>>>>>>
A::A()
A::peek() cnt=0
A::peek() cnt=0
A::~A()
<<<<<<<<<<<<<<<<<<<<<

Apparently the operators ++ and -- of class A are never executed, although my understanding is that they should be used by tmp<a > to do the reference counting?

More importantly, if I replace the line "A a;" in the code above with "A *a=new A();" I get the following output with a core dump:
>>>>>>>>>>>>>>>>>>>>>
A::A()
A::peek() cnt=0
A::op++() returns 1
A::peek() cnt=1
A::~A()
A::~A()
*** glibc detected *** ./test: double free or corruption (fasttop): 0x08094120 ***
....
Aborted (core dumped)
<<<<<<<<<<<<<<<<<<<<<

Here the reference count actually is increased, but nevertheless the pointer "A *a" seems to be freed twice.
What do I need to change to make the example finish without an error? Do I have to test the reference count myself in okToDelete()? I also tried to initialze cnt=1 or even cnt=2 in the constructor A::A(), but it doesn't help.


Thank you
Nadine
  Reply With Quote

Old   July 24, 2008, 06:30
Default Hello Nadine Have a look at
  #6
New Member
 
Miguel Gomez
Join Date: Mar 2009
Posts: 1
Rep Power: 0
mgomez is on a distinguished road
Hello Nadine

Have a look at $FOAM_SRC/OpenFOAM/fields/tmp/refCount.H for the details of the implementation. You need to inherit your class A from refCount, then you can forget about doing any counting yourself.

As to your first question, your local variable "A a;" is allocated on the stack, not on the heap. Therefore the tmp class doesn't have to keep track of the reference count.

As to your second question, yes, okToDelete is the place to check whether the count has become zero. Only then okToDelete can return True.

Again, check how it is done in refCount.H, and it will be straightforward to code your own refcountable class.

HTH
Miguel
mgomez is offline   Reply With Quote

Old   July 24, 2008, 09:06
Default Thank you Miguel! You helped m
  #7
nadine
Guest
 
Posts: n/a
Thank you Miguel! You helped me make a big step ahead.

I thought okToDelete() was some extra option to prevent references from being destroyed although their counter is zero, like a "Do you really want to quit?" dialog. But your explanations and a look into refCount.H and tmpI.H made it clear.

Thank you
Nadine
  Reply With Quote

Old   November 18, 2008, 15:23
Default Can any one explain the differ
  #8
Senior Member
 
Maka Mohu
Join Date: Mar 2009
Posts: 305
Rep Power: 9
maka is on a distinguished road
Can any one explain the difference between:

{
tmp<scalarfield> xTmp = ...;
scalarField x = ...;

{
tmp<scalarfield> xTmp = ...;
scalarField x = ...;
}
}

in terms of when the memory is free from the variables.

Thanks,
Maka.
maka is offline   Reply With Quote

Old   January 22, 2009, 07:52
Default to reproduce the error: - V1.
  #9
Senior Member
 
Maka Mohu
Join Date: Mar 2009
Posts: 305
Rep Power: 9
maka is on a distinguished road
to reproduce the error:
- V1.3
- bug correction in here is implemented.
- add to the beginning of the definition of LES models correct(const tmp<voltensorfield>& gradU)

Info <<"1" << average(mag(gradU)) << endl;
Info <<"2" << average(mag(gradU)) << endl;
Info <<"3" << average(mag(gradU)) << endl;

if the variable gradU is used more than once or twice within the scope of the function definition (inside correct function) it gives:
FOAM FATAL ERROR : temporary deallocated

From function const T& tmp<t>::operator()() const
in file ../maka/OpenFOAM/OpenFOAM-1.3/src/OpenFOAM/lnInclude/tmpI.H at line 190.

Thanks.
maka is offline   Reply With Quote

Old   January 22, 2009, 08:08
Default Maka, 1. I don't think you
  #10
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: http://olesenm.github.io/
Posts: 777
Rep Power: 18
olesen will become famous soon enough
Maka,

1. I don't think you should expect any bugfixes for version 1.3, version 1.5.x is current.

2. The code you showed (using a tmp value several times) should always result in a fatal error.
You sent mag() a tmp, so of course it freed it!
olesen is offline   Reply With Quote

Old   January 22, 2009, 08:17
Default Unfortunately, two errors (apa
  #11
Senior Member
 
Hrvoje Jasak
Join Date: Mar 2009
Location: London, England
Posts: 1,763
Rep Power: 21
hjasak will become famous soon enough
Unfortunately, two errors (apart from Mark not knowing what he's talking about):

First const tmp<voltensorfield>& gradU is wrong: it is a reference to a temporary, which gets deleted. This should read
const voltensorfield& gradU

Second,

tmp<voltensorfield> gradU = fvc::grad(U);
Info <<"1" << average(mag(gradU)) << endl;
Info <<"2" << average(mag(gradU)) << endl;
Info <<"3" << average(mag(gradU)) << endl;



does not work. I do not have a strong opinion if it should - it violates the rules of using a tmp, so I'm not bothered if it fails.

The correct and working code reads:

volTensorField gradU = fvc::grad(U);
Info <<"1" << average(mag(gradU)) << endl;
Info <<"2" << average(mag(gradU)) << endl;
Info <<"3" << average(mag(gradU)) << endl;


I will change the LES models over here.

Hrv
__________________
Hrvoje Jasak
Providing commercial FOAM/OpenFOAM and CFD Consulting: http://wikki.co.uk
hjasak is offline   Reply With Quote

Old   January 22, 2009, 08:58
Default It seems to be a bug since the
  #12
Senior Member
 
Maka Mohu
Join Date: Mar 2009
Posts: 305
Rep Power: 9
maka is on a distinguished road
It seems to be a bug since the following is the declaration of correct() member function that is used in most LES models in the standard release 1.4.1 (I did not check later versions):
void Smagorinsky::correct(const tmp<voltensorfield>& gradU).

If you could explain what are the rules of using tmp and what do we gain from using tmp. I will be very grateful. Thanks.
maka is offline   Reply With Quote

Old   January 22, 2009, 08:59
Default If you need a quick fix do gra
  #13
Senior Member
 
Hrvoje Jasak
Join Date: Mar 2009
Location: London, England
Posts: 1,763
Rep Power: 21
hjasak will become famous soon enough
If you need a quick fix do gradU()} in function calls.
__________________
Hrvoje Jasak
Providing commercial FOAM/OpenFOAM and CFD Consulting: http://wikki.co.uk
hjasak is offline   Reply With Quote

Old   January 22, 2009, 09:02
Default I used to do that all the time
  #14
Senior Member
 
Maka Mohu
Join Date: Mar 2009
Posts: 305
Rep Power: 9
maka is on a distinguished road
I used to do that all the time but I do not understand what I'm doing that is why I would be thankful if you could explain:
(1) what are the rules of using tmp?
(2) what do we gain from using tmp?
Thanks.
maka is offline   Reply With Quote

Old   January 22, 2009, 10:25
Default Hello developers, It would be
  #15
Senior Member
 
dmoroian's Avatar
 
Dragos
Join Date: Mar 2009
Posts: 647
Rep Power: 11
dmoroian is on a distinguished road
Hello developers,
It would be very nice if you take a bit of your time and put some guide lines "why, when, how" to use temporary objects.
I've searched the forum and there are many places (~100) where this subject is approached but it still lacks the above basics.

Dragos
dmoroian is offline   Reply With Quote

Reply

Thread Tools
Display Modes

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 On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Example of use of the solidParticlesolidParticleCloud classes alberto OpenFOAM Running, Solving & CFD 27 July 9, 2009 03:00
What is the role of tmp%2360T class objects nicasch OpenFOAM Running, Solving & CFD 0 September 17, 2008 03:29
Adding functionality to classes sergio OpenFOAM 9 March 13, 2008 06:18
Invalid pointer handling in tmp%2360T class mbeaudoin OpenFOAM 1 April 24, 2007 12:57
Parallel Computing Classes at San Diego Supercomputer Center Jan. 20-22 Amitava Majumdar Main CFD Forum 0 January 5, 1999 13:00


All times are GMT -4. The time now is 14:06.