CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Post-Processing (http://www.cfd-online.com/Forums/openfoam-post-processing/)
-   -   Output file with OpenFOAM header (http://www.cfd-online.com/Forums/openfoam-post-processing/66619-output-file-openfoam-header.html)

sega July 20, 2009 09:12

Output file with OpenFOAM header
 
Hello again.

Is there a way of putting the standard OpenFOAM file header on top of an output file I created with something like this?
Code:

OFstream os ("p");
os << faceCenterPressure;


sega July 22, 2009 02:41

Sorry I have to push this, but this problem is crucial in one of my efforts.
I'm producing a lot of files with a home-made tool.
Editing these files by copy&pasting file headers inside is critically affecting the whole performance ...

What I'm searching for is a possibilty to put the OpenFOAM header on top of an output file. Furthermore I need to specify the class and object entry!

gschaider July 22, 2009 07:29

Quote:

Originally Posted by sega (Post 223590)
Sorry I have to push this, but this problem is crucial in one of my efforts.
I'm producing a lot of files with a home-made tool.
Editing these files by copy&pasting file headers inside is critically affecting the whole performance ...

What I'm searching for is a possibilty to put the OpenFOAM header on top of an output file. Furthermore I need to specify the class and object entry!

The functionality you require is in the IOobject-class (that is why you always have to construct one when you add a new field). Go to the Doxygen and there click yourself down the inheritance-tree until you find a class that does what you want (IOList or IOdictionary might be what you need)

Bernhard

sega July 22, 2009 07:45

I'm not familiar with this Doxygen thing but I haven't found an "inheritence tree".
Just some crypical "class reference".

l_r_mcglashan July 22, 2009 07:50

Have a look at:

IOobject::writeHeader or IOobjectWriteHeader.C

That should give you enough information.

To use Doxygen, have a look here:

http://foam.sourceforge.net/doc/Doxy...1IOobject.html

And scroll down to the public member functions section.

Oh, and look at:

http://foam.sourceforge.net/doc/Doxy...ph_legend.html

to see how the diagrams work.

gschaider July 22, 2009 11:27

Quote:

Originally Posted by sega (Post 223625)
I'm not familiar with this Doxygen thing but I haven't found an "inheritence tree".
Just some crypical "class reference".

And in the class reference you find an inheritance-diagram. In that you find that only one class inherits from IOobject but if you click on that all the "grandchildren" is revealed. But I don't want to spoil the whole fun for you, as you'll probably want to familiarize yourself with Doxygen if you want to do any serious programming in OpenFOAM

Bernhard

sega July 27, 2009 11:15

I'm afraid I can't solve this mystery on my own.
I toyed around with some strange commands.

Code:

        OFstream osP (directory/"p");
        faceCenterPressure.writeHeader(osP);
        osP << faceCenterPressure;

is my best guess, but it's not working:

Code:

error: ‘class Foam::scalarField’ has no member named ‘writeHeader’

gschaider July 28, 2009 08:49

Quote:

Originally Posted by sega (Post 224294)
I'm afraid I can't solve this mystery on my own.
I toyed around with some strange commands.

Code:

        OFstream osP (directory/"p");
        faceCenterPressure.writeHeader(osP);
        osP << faceCenterPressure;

is my best guess, but it's not working:

Code:

error: ‘class Foam::scalarField’ has no member named ‘writeHeader’

What kind of "thing" is faceCenterPressure, anyway? Let's assume it is a scalarList. Then try something like (I'm only doing this from the Information available in the Doxygen, the details may be wrong)
Code:

IOList<scalar> faceCenterPressure(
  IOobject(
            "faceCenterPressure",
            runTime.timeName(),
            mesh,
            IOobject::READ_IF_PRESENT,
            IOobject::AUTO_WRITE
        )
 );

that should be read if present (zero-size otherwise) and automagically written whenever all the other stuff is written. WITH A HEADER. And you can use it like any other scalarList

sega July 28, 2009 09:25

This faceCenterPressure is a scalarField!

Code:

scalarField faceCenterPressure(facesSet.size());
which is collecting pressure values at specific face centers and is written to a file with OFstream!
Have a look:
(Note: surfaceScalarField ps = fvc::interpolate(p);)

Code:

for (label k=0; k<facesSet.size(); k++)
    {
        int faceNumber = faces[k];
        faceCenterPressure[k] = ps[faceNumber];

        fileName directory = runTime.path()/"boundaryData"/setName/runTime.timeName();
        mkDir(directory);

        OFstream osP (directory/"p");
        osP << faceCenterPressure;
  }

If I put your suggested code snipped anywhere inside the {}-brackets I get this error:

Code:

Make/linux64GccDPOpt/listFaceSet.o: In function `Foam::IOList<double>::type() const':
listFaceSet.C:(.text._ZNK4Foam6IOListIdE4typeEv[Foam::IOList<double>::type() const]+0x3): undefined reference to `Foam::IOList<double>::typeName'
Make/linux64GccDPOpt/listFaceSet.o: In function `Foam::IOList<double>::IOList(Foam::IOobject const&)':
listFaceSet.C:(.text._ZN4Foam6IOListIdEC1ERKNS_8IOobjectE[Foam::IOList<double>::IOList(Foam::IOobject const&)]+0x46): undefined reference to `Foam::IOList<double>::typeName'
collect2: ld returned 1 exit status

I assume there is something wrong with the "type" of field (scalarList, scalarField, or??) which is causing this error.

Still big question: Will your suggestion render this OFstream-output-command useless ?!

gschaider July 28, 2009 12:40

Quote:

Originally Posted by sega (Post 224406)
This faceCenterPressure is a scalarField!

My example was done without knowing this

Quote:

Originally Posted by sega (Post 224406)
I assume there is something wrong with the "type" of field (scalarList, scalarField, or??) which is causing this error.

Please go to the inheritance diagram in Doxygen. You will find that IOList ist a List with IO stuff added. How a Field with added IO would be called is left as an exercise to the reader.

Quote:

Originally Posted by sega (Post 224406)
Still big question: Will your suggestion render this OFstream-output-command useless ?!

Definitly. Use it the way stuff in the createFields.H of any solver is used

sega July 28, 2009 13:45

Quote:

Originally Posted by gschaider (Post 224429)
Please go to the inheritance diagram in Doxygen. You will find that IOList ist a List with IO stuff added. How a Field with added IO would be called is left as an exercise to the reader.

Dear Bernhard.

I appreciate your didactic intention.
But this inheritance diagram is filling two pages on my screen.
I have to confess I'm totally swamped with this.
Maybe this is not the right choice for starting to learn how to read the Doxygen guide.

I don't even have the slightest idea where to look, not to talk about finding a solution...

Sorry, I need further input ...

l_r_mcglashan July 28, 2009 13:59

This is the way I would see it (correct if I'm wrong).

scalarField is just a typedef: Field<scalar>.

If you look at the inheritance diagrams, you should be able to see that all the dimensioned fields, IOList, IOField and other things all inherit from regIOobject which inherits from IOobject.

So you may have:
scalarField faceCentrePressure(IOobject..blah..);
IOField<scalar> faceCentrePressure(IOobject..blah..);

Does that help?

sega July 28, 2009 14:22

Yes.

Code:

IOField<scalar> faceCentrePressure(IOobject..blah..);
is compiling. But it's not doing what I want.
When running my code
Code:

    surfaceScalarField ps = fvc::interpolate(p);

    scalarField faceCenterPressure(facesSet.size());
     
    for (label k=0; k<facesSet.size(); k++)
    {
        int faceNumber = faces[k];

        faceCenterPressure[k] = ps[faceNumber];

        fileName directory = runTime.path()/"boundaryData"/setName/runTime.timeName();
        mkDir(directory);

        IOField<scalar> faceCenterPressure
        (
          IOobject
          (
        "faceCenterPressure",
        runTime.timeName(),
        mesh,
        IOobject::READ_IF_PRESENT,
        IOobject::AUTO_WRITE
          )
        );

        OFstream osP (directory/"p");
        osP << faceCenterPressure;
        }

    };

on a case it tries to read the file faceCenterPressure in the time step directories instead of writing the faceCenterPressure scalarField into a corresponding (and equally named) file...

gschaider July 29, 2009 05:19

Quote:

Originally Posted by sega (Post 224450)
Yes.

Code:

IOField<scalar> faceCentrePressure(IOobject..blah..);
is compiling. But it's not doing what I want.
When running my code
Code:

    surfaceScalarField ps = fvc::interpolate(p);

    scalarField faceCenterPressure(facesSet.size());
     
    for (label k=0; k<facesSet.size(); k++)
    {
        int faceNumber = faces[k];

        faceCenterPressure[k] = ps[faceNumber];

        fileName directory = runTime.path()/"boundaryData"/setName/runTime.timeName();
        mkDir(directory);

        IOField<scalar> faceCenterPressure
        (
          IOobject
          (
        "faceCenterPressure",
        runTime.timeName(),
        mesh,
        IOobject::READ_IF_PRESENT,
        IOobject::AUTO_WRITE
          )
        );

        OFstream osP (directory/"p");
        osP << faceCenterPressure;
        }

    };


Quote:

Originally Posted by sega (Post 224450)
on a case it tries to read the file faceCenterPressure in the time step directories

That's what READ_IF_PRESENT does
Quote:

Originally Posted by sega (Post 224450)
instead of writing the faceCenterPressure scalarField into a corresponding (and equally named) file...

That is what IOobjects do with the write()-method (to find methods "that should be there" click in the Doxygen on "List all members" and browse)

And currently you're writing stuff at every iteration of the loop. Basically you only need one faceCenterPressure (outside the loop)
Code:

       
IOField<scalar> faceCenterPressure
        (
          IOobject
          (
        "faceCenterPressure",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ,
        IOobject::NO_WRITE
          )
      ,facesSet.size()
        );

In the loop get rid of all the writing stuff and after the loop do
Code:

faceCenterPressure.write()
It writes to the current time-directory. How to get the stuff to the directory you want should be possible but I'd have to go to the Doxygen myself to see how to do that

sega July 29, 2009 09:48

Yes. Thats working. Just great!
The files containing the correct values from the faceCenterPressure variable are written in the time directories with headers!

If you can point out to me how to write these files into a different location, this would round up this part of the problem.

The next problem is the following:
The output file hast to have two specific entries in its header
  • class: scalarAveragedField
  • object: values
How can I manage this?!

l_r_mcglashan July 30, 2009 06:47

Does changing the second argument of IOobject to the folder you want the field to be saved to not work? So instead of runTime.timeName() having, say, "thisFolder".

Not sure how you would write different entries to your header. You could either change the IOobjectWriteHeader.C file or write to the file directly.

sega July 31, 2009 11:42

Quote:

Originally Posted by l_r_mcglashan (Post 224692)
Does changing the second argument of IOobject to the folder you want the field to be saved to not work? So instead of runTime.timeName() having, say, "thisFolder".

I have toyed around with this entry, but haven't found a way of managing a different directory so far.

Quote:

Not sure how you would write different entries to your header. You could either change the IOobjectWriteHeader.C file or write to the file directly.
If I change anything in IOobjectWriteHeader.C will this be a "global" effect?
So all other fields will also be written in the manner I specify there?
Thats definitefly not what I intend to do, as this should be limited to the special case I'm working with ...

So, what do you mean by "writing directly to the file"?


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