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

Duplicate GeometricField

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   June 4, 2008, 16:58
Default Hi! I hope that not only user
  #1
reimund
Guest
 
Posts: n/a
Hi!
I hope that not only users, but also developers are active in this list, because I have a rather technical question.

How can I duplicate a GeometricField?
I received some OpenFOAM solver code, which creates locally several volScalarFields, volVectorFields etc. I want to #include this code into another solver function without modifying it. After the #include the function has to return a list containing pointers to some of those fields.

However, because the local fields are discarded on function return, later use of the returned pointers causes a segmentation fault. How can I get out of this?
For example I have a local "volScalarField p". I tried to create a static copy q with "static volScalarField q(p);". When I return the pointer &q, this should be still valid, because the static variable is not discarded. But I still have a segmentation fault, maybe because the copy constructor q(p) only does a shallow copy?
I also tried many things with clone() and autoPtr<volscalarfield>, but none of them helped me to create a static volScalarField from p.

What is the correct approach?

Reimund
  Reply With Quote

Old   June 4, 2008, 21:40
Default Hi Reimund It seems that th
  #2
Senior Member
 
su_junwei's Avatar
 
su junwei
Join Date: Mar 2009
Location: Xi'an China
Posts: 151
Rep Power: 20
su_junwei is on a distinguished road
Send a message via MSN to su_junwei
Hi Reimund

It seems that the assigment operator "=" in GeometricField is a copy assigment.
Returning the local variable of GeometericField type will cause a problem??

If several GeometericField objects need to be returned, use the class of "PtrList" passed as a argument.(That return PtrList directly will also cause a problem, for there is not a clone() function in GeometericField !!) or create a new class like "combustionMixture" located at
/src/thermophysicalModels/combustion/mixtureThermos/mixtures/combustionMixture/"

Help this helps

Su Junwei
su_junwei is offline   Reply With Quote

Old   June 5, 2008, 03:05
Default Well, You can duplicate a geom
  #3
Senior Member
 
Hrvoje Jasak
Join Date: Mar 2009
Location: London, England
Posts: 1,907
Rep Power: 33
hjasak will become famous soon enough
Well, You can duplicate a geometric field by calling a copy constructor, which is trivial:

volScalarField p2 = p;

What you need to worry about is a return type from your function - are you returning a reference to a temporary rather than a copy?

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

Old   June 5, 2008, 17:33
Default Thanks for your answers. I thi
  #4
reimund
Guest
 
Posts: n/a
Thanks for your answers. I think I am slowly understanding more about the problem. Below I post a small piece of code in the hope that you might try, what goes wrong, in case my explanations are not clear enough.

In the initialize() method the #included files represent the part that I wish not to change. The returned pointer to the field p is simplified for the list of field pointers to be returned.

As Hrvoje said, the copy constructor "static volScalarField p2=p;" does _in principle_ what I need, copying the local field into a static field to which a pointer can be returned.
BUT: I had to modify the declarations of the variables runTime and mesh into static declaration. These two are referenced in the field constructors, and apparently the static copy p2 can't be used, if the original runTime and mesh aren't valid anymore.

Is there any possiblity, how I can copy runTime and mesh into static variables _after_ the #includes, and plug these static copies into the static p2?

Reimund

This code I placed into the solvers/incompressible/icoFoam directory and compiled it like icoFoam.C:

#include "fvCFD.H"

volScalarField *initialize(int argc, char *argv[]){
#include "setRootCase.H"
#include "createTime.H" //here I had to change "Foam::Time runTime" to "static Foam::Time runTime"
#include "createMesh.H" //here I had to change "fvMesh mesh" to "static fvmesh mesh"
#include "createFields.H" //no changes needed

static volScalarField p2=p;
return &p;
}

int main(int argc, char *argv[])
{
volScalarField *p=initialize(argc,argv);
// test if p is valid:
Foam::mag(*p);
printf("If no exception has been reported, the pointer was valid.\n");
}
  Reply With Quote

Old   June 5, 2008, 18:09
Default Static variables (I believe) h
  #5
Senior Member
 
Sandeep Menon
Join Date: Mar 2009
Location: Amherst, MA
Posts: 403
Rep Power: 25
deepsterblue will become famous soon enough
Static variables (I believe) have a longer lifetime during the program run, and is generally a bad choice for your problem.
I'd suggest that you create a tmp<volscalarfield> within your function and return that. No messy pointers to deal with, and the object is destroyed automatically when it goes out of scope.
Am I right, Hrv?
__________________
Sandeep Menon
University of Massachusetts Amherst
https://github.com/smenon
deepsterblue is offline   Reply With Quote

Old   June 5, 2008, 18:35
Default >Static variables (I believe)
  #6
reimund
Guest
 
Posts: n/a
>Static variables (I believe) have a longer lifetime during the program run, and is generally a bad
>choice for your problem.

Why? A longer lifetime than local variables is exactly what I need. My problem is, that the included code creates local fields. And I have to get those fields out of my initialize() function.

>I'd suggest that you create a tmp<volscalarfield> within your function and return that. No messy >pointers to deal with, and the object is destroyed automatically when it goes out of scope.

Destroyed out-of-scope opbjects is what I want to _avoid_!

Reimund
  Reply With Quote

Old   June 5, 2008, 22:41
Default Hi Reimund Return the refe
  #7
Senior Member
 
su_junwei's Avatar
 
su junwei
Join Date: Mar 2009
Location: Xi'an China
Posts: 151
Rep Power: 20
su_junwei is on a distinguished road
Send a message via MSN to su_junwei
Hi Reimund

Return the reference of a local variable is not safe even if it is static, and please refer the book "effective c++ (item 23)" of scott Meyers.

try the code below

#include "fvCFD.H"

volScalarField initialize(int argc, char *argv[]){
#include "setRootCase.H"
#include "createTime.H" //here I had to change "Foam::Time runTime" to "static Foam::Time runTime"
#include "createMesh.H" //here I had to change "fvMesh mesh" to "static fvmesh mesh"
#include "createFields.H" //no changes needed

return p;
}

int main(int argc, char *argv[])
{
volScalarField p=initialize(argc,argv);
// test if p is valid:
Foam::mag(p);
printf("If no exception has been reported, the pointer was valid.\n");
}

OR


#include "fvCFD.H"

void initialize(int argc, char *argv[], volScalarField & p){
#include "setRootCase.H"
#include "createTime.H" //here I had to change "Foam::Time runTime" to "static Foam::Time runTime"
#include "createMesh.H" //here I had to change "fvMesh mesh" to "static fvmesh mesh"
#include "createFields.H" //no changes needed
}

int main(int argc, char *argv[])
{
// create volScalarField p;
.....

initialize(argc,argv,p);
// test if p is valid:
Foam::mag(p);
printf("If no exception has been reported, the pointer was valid.\n");
}

Su Junwei
su_junwei is offline   Reply With Quote

Old   June 5, 2008, 22:48
Default Can you rewrite it like this?
  #8
Senior Member
 
Sandeep Menon
Join Date: Mar 2009
Location: Amherst, MA
Posts: 403
Rep Power: 25
deepsterblue will become famous soon enough
Can you rewrite it like this?

tmp<volscalarfield> initialize(int argc, char *argv[]){
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFields.H"

tmp<volscalarfield> p2 = new volScalarField(p);
return p2;
}

When you call initialize() in main, it should return a copy of 'p'. This still doesn't solve runTime and mesh going out of scope, though; and you're right - instantiating them as static is one way of doing it. Are you trying to do this to hide the #include statements in one convenient function?
__________________
Sandeep Menon
University of Massachusetts Amherst
https://github.com/smenon
deepsterblue is offline   Reply With Quote

Old   June 7, 2008, 15:00
Default >Can you rewrite it like this?
  #9
reimund
Guest
 
Posts: n/a
>Can you rewrite it like this?
Sure, but it doesn't compile.

>tmp<volscalarfield> p2 = new volScalarField(p);
There is no tmp<volscalarfield> constructor from a volScalarField*.

If I remove the "new", I get the following output:

...
>Reading field U
>Reading/calculating face flux field phi
>terminate called after throwing an instance of 'std::length_error'
> what(): basic_string::_S_create
>Aborted (core dumped)

Because you repeat that I should use tmp<> to return the local field, could you please explain, how this would internally solve the task of converting the local field into an outside accessible field (assuming it worked)?

>Are you trying to do this to hide the #include statements in one convenient function?
Yes, it could be phrased like this.

Thank you! Reimund
  Reply With Quote

Old   June 9, 2008, 14:47
Default Hmm... Maybe this will work:
  #10
Senior Member
 
Sandeep Menon
Join Date: Mar 2009
Location: Amherst, MA
Posts: 403
Rep Power: 25
deepsterblue will become famous soon enough
Hmm... Maybe this will work:

tmp<volscalarfield> initialize(int argc, char *argv[]){
#include "setRootCase.H"
#include "createTime.H"
#include "createMesh.H"
#include "createFields.H"

tmp<volscalarfield> p2(new volScalarField(p));
return p2;
}

You'd be able to return only a single field using this function, though. All other fields created in createFields.H still have only local scope.
Using the tmp<> approach is a good way to ensure proper garbage collection.
__________________
Sandeep Menon
University of Massachusetts Amherst
https://github.com/smenon
deepsterblue is offline   Reply With Quote

Reply


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


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to convert from GeometricField to fvMatrix waynezw0618 OpenFOAM Running, Solving & CFD 2 January 8, 2021 17:35
Manipulation of cellvalue of a geometricField ivan_cozza OpenFOAM Running, Solving & CFD 2 September 25, 2008 14:58
Create GeometricField without IOobject nadine OpenFOAM Running, Solving & CFD 3 August 15, 2008 10:24
Accessing data of geometricField bird OpenFOAM Running, Solving & CFD 1 August 28, 2007 19:21
Duplicate mesh in FIELDVIEW Jing Siemens 1 August 4, 2003 04:08


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