|
[Sponsors] |
July 4, 2008, 18:35 |
Hi!
I would like to ask if yo
|
#1 |
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 |
|
July 5, 2008, 15:21 |
A tmp<> object is used in the
|
#2 |
Senior Member
Sandeep Menon
Join Date: Mar 2009
Location: Amherst, MA
Posts: 403
Rep Power: 25 |
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. |
|
July 5, 2008, 17:00 |
"Each tmp<> object has a refer
|
#3 |
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 |
|
July 6, 2008, 04:47 |
"Each tmp<> object has a refer
|
#4 |
Senior Member
Martin Beaudoin
Join Date: Mar 2009
Posts: 332
Rep Power: 22 |
"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 |
|
July 24, 2008, 06:13 |
Hi!
After a few weeks I'm c
|
#5 |
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 |
|
July 24, 2008, 07:30 |
Hello Nadine
Have a look at
|
#6 |
New Member
Miguel Gomez
Join Date: Mar 2009
Posts: 1
Rep Power: 0 |
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 |
|
July 24, 2008, 10:06 |
Thank you Miguel! You helped m
|
#7 |
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 |
|
November 18, 2008, 15:23 |
Can any one explain the differ
|
#8 |
Senior Member
Maka Mohu
Join Date: Mar 2009
Posts: 305
Rep Power: 18 |
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. |
|
January 22, 2009, 07:52 |
to reproduce the error:
- V1.
|
#9 |
Senior Member
Maka Mohu
Join Date: Mar 2009
Posts: 305
Rep Power: 18 |
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. |
|
January 22, 2009, 08:08 |
Maka,
1. I don't think you
|
#10 |
Senior Member
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40 |
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! |
|
January 22, 2009, 08:17 |
Unfortunately, two errors (apa
|
#11 |
Senior Member
Hrvoje Jasak
Join Date: Mar 2009
Location: London, England
Posts: 1,907
Rep Power: 33 |
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 |
|
January 22, 2009, 08:58 |
It seems to be a bug since the
|
#12 |
Senior Member
Maka Mohu
Join Date: Mar 2009
Posts: 305
Rep Power: 18 |
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. |
|
January 22, 2009, 08:59 |
If you need a quick fix do gra
|
#13 |
Senior Member
Hrvoje Jasak
Join Date: Mar 2009
Location: London, England
Posts: 1,907
Rep Power: 33 |
If you need a quick fix do gradU()} in function calls.
__________________
Hrvoje Jasak Providing commercial FOAM/OpenFOAM and CFD Consulting: http://wikki.co.uk |
|
January 22, 2009, 09:02 |
I used to do that all the time
|
#14 |
Senior Member
Maka Mohu
Join Date: Mar 2009
Posts: 305
Rep Power: 18 |
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. |
|
January 22, 2009, 10:25 |
Hello developers,
It would be
|
#15 |
Senior Member
Dragos
Join Date: Mar 2009
Posts: 648
Rep Power: 20 |
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 |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Example of use of the solidParticlesolidParticleCloud classes | alberto | OpenFOAM Running, Solving & CFD | 28 | June 5, 2017 04:23 |
What is the role of tmp%2360T class objects | nicasch | OpenFOAM Running, Solving & CFD | 0 | September 17, 2008 04: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 13:57 |
Parallel Computing Classes at San Diego Supercomputer Center Jan. 20-22 | Amitava Majumdar | Main CFD Forum | 0 | January 5, 1999 13:00 |