CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Perfoming operation if field is present (https://www.cfd-online.com/Forums/openfoam-programming-development/69100-perfoming-operation-if-field-present.html)

sega October 12, 2009 08:49

Perfoming operation if field is present
 
Hello World.

I'm trying to make a tool work with a simple condition:
If a field (k) exists perfom an operation, if a different field (nuSgs) exists perform an other operation, if non of these two exist, just do nothing.

I'm not sure how to check if a field is present, but I'm sure you can help me.

Thank you!
S.

niklas October 12, 2009 09:03

Is this what you're after...
Code:

    IOobject header
    (
        name,
        mesh.time().timeName(),
        mesh,
        IOobject::NO_READ
    );

    if (header.headerOk())
    {
        latida....
    }
    else
    {
    }

my example is taken from
applications/solvers/multiphase/twoPhaseEulerFoam/phaseModel/phaseModel/phaseModel.C

sega October 12, 2009 09:25

Maybe. I have thought about something like this.
But now I'm having a different problem.

How can I read the field itself?
And how can I prevent the tool from crashing if the field file is not present?!

I have tried:
Code:

    // Reading field k
    volScalarField k
    (
        IOobject
        (
        "k",
        runTime.timeName(),
        mesh,
        IOobject::READ_IF_PRESENT,
        IOobject::AUTO_WRITE
        ),
        mesh
    );

    // Reading field nuSgs
    volScalarField nuSgs
    (
        IOobject
        (
        "nuSgs",
        runTime.timeName(),
        mesh,
        IOobject::READ_IF_PRESENT,
        IOobject::AUTO_WRITE
        ),
        mesh
    );

But this doesn't seem to be the right way...

niklas October 12, 2009 09:32

of course that wont work.

just think!!!

what will the k-field be if it cant read it?

grep READ_IF_PRESENT in the solver/incompressible
and you might find this.
Code:

volScalarField hTotal
(
    IOobject
    (
        "hTotal",
        runTime.timeName(),
        mesh,
        IOobject::READ_IF_PRESENT,
        IOobject::AUTO_WRITE
    ),
    h+h0
);

see the stuff that reads 'h+h0', thats what hTotal will be set to if it cant read it.

sega October 12, 2009 09:48

Hmm. But I don't see how this can be useful for me.
What do I have to do?! Where is the link to my problem?

sega October 13, 2009 12:12

Quote:

Originally Posted by niklas (Post 232258)
what will the k-field be if it cant read it?

I have absolutely no idea. Maybe it will be nothing at all?!
So what's wrong with my idea:
Read the field if present and perform an operation if the header is ok.

So the problem is that the field file was attempted to be read - although it's NOT present! So whats READ_IF_PRESENT used for, if not exactly this?

I still don't see the link between my problem and your code snipped:
What's the point in summing up two different fields (h,h0) when reading hTotal?

To make this clear again:
  1. I want to read a file containing field value if the file is present
  2. If the file (or maybe field variable at this point) is present perform an operation to the field.
  3. If the file or field variable is not present, simply do nothing

niklas October 15, 2009 02:26

Quote:

Originally Posted by sega (Post 232457)
I have absolutely no idea. Maybe it will be nothing at all?!
So what's wrong with my idea:
Read the field if present and perform an operation if the header is ok.

simple classes, like for instance label and scalar, allow default initialization
so if you write the code

double alpha;

it is a perfectly valid code, except what you really have written is

double alpha(0.0)

because if you dont set an initial value, it will be zero.
you can not create a complex class like this, so

volScalarField beta;

will not work, because a volScalarField needs to know dimension, bc's and size of the field,
upon creation.

Quote:

Originally Posted by sega (Post 232457)
So the problem is that the field file was attempted to be read - although it's NOT present! So whats READ_IF_PRESENT used for, if not exactly this?

I still don't see the link between my problem and your code snipped:
What's the point in summing up two different fields (h,h0) when reading hTotal?

To make this clear again:
  1. I want to read a file containing field value if the file is present
  2. If the file (or maybe field variable at this point) is present perform an operation to the field.
  3. If the file or field variable is not present, simply do nothing

READ_IF_PRESENT means it will read the file if it exists.
But if it doesnt exist, it must take its value from somewhere else.
you can not create a volScalarField that is uninitialized, you have to set it to something.
if the variable exists, it must have a value.
(and since volScalarField doesnt have a default constructor, you have to set its value)
so in the constructor you give it two options,
the first option is to set the field according to the file,
the second option is to set the field according to the specified value if that file didnt exist
(in this case hTotal = h + h0).

sega October 19, 2009 13:27

Dear niklas.

I had to think about this for a while and tried to use it on my code.
I haven't succeeded so far and will post my questions below.

Quote:

Originally Posted by niklas (Post 232704)
READ_IF_PRESENT means it will read the file if it exists.
But if it doesnt exist, it must take its value from somewhere else.
you can not create a volScalarField that is uninitialized, you have to set it to something.
if the variable exists, it must have a value.
(and since volScalarField doesnt have a default constructor, you have to set its value)
so in the constructor you give it two options,
the first option is to set the field according to the file,
the second option is to set the field according to the specified value if that file didnt exist
(in this case hTotal = h + h0).

So I do understand the above and basically know what to do, but haven't worked out a way of making it run inside my code.

Considering the case the file does not exist:
I need a value "from somewhere else"?
Where do I get this value?
I have to use an already initialized variable and assign it?
So, how do I initialize a variable which I can assign to a volScalarField?
I have tried something like this, but it doesn't work out:
Code:

volScalarField k0(1);
Consider the case I have worked out a way of initializing an empty field:
How do I actually assign it to the variable?
I'm confused by the example above:
Is hTotal the file to be read? Or is it h or h0?
Which one is the value with data from somewhere else?

You see I actually don't understand very much of what I'm dealing with.
I'm really hoping for your input in this matter.

Consider a next thought of mine:
If I worked out a way of making the above possible I have an empty field named after the file that should be there (but is not)?
Further down the road of the tool I'm manipulating the fields and write them to new files but with equal names.
So will there be a field named after this empty field in the end?

I'm so sorry to make such a stupid impression in this matter, but I don't see the mystery behind these file operations.

Hope for your answers & see you.
sega

niklas October 20, 2009 03:00

Havent you tried just this?

Code:

    IOobject kHeader
    (
        "k",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ
    );

    if (kHeader.headerOk())
    {
        Info<< "Reading k.\n" << endl;

        volScalarField k
        (
            IOobject
            (
                "k",
                runTime.timeName(),
                mesh,
                IOobject::MUST_READ,
                IOobject::AUTO_WRITE
            ),
            mesh
        );
        // Here I do whatever...
    }


sega October 20, 2009 03:43

No. But this looks very promising.
I will give it a try in the next days and will get back to you.

sega October 20, 2009 09:44

Quote:

Originally Posted by niklas (Post 233322)
Havent you tried just this?

Works! Thank you!!!

Now, how can I check weather the variable is present or not?
Suppose one field (k) is present and was read from file, while the other (nuSgs) is not present and was not read from file, so the variable doesn't exist.

So, what I need is a condition to determine if the variables was initialized.

Do you know, what I mean?

sega October 21, 2009 05:53

Quote:

Originally Posted by sega (Post 233390)
So, what I need is a condition to determine if the variables was initialized.

Sorry, to quote myself, but I have thought of a way of doing the above.
Unfortunately my idea didn't turn out the way it should be, so I'm bothering you again.

To check if a field was successfully read I thought about introducing a variable kPresent just like this

Code:

int kPresent = 0;

  IOobject kHeader
    (
        "k",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ
    );

    if (kHeader.headerOk())
    {
        kPresent = 1;    \\ Successfully read from file!
        Info<< "Reading k.\n" << endl;

        volScalarField k
        (
            IOobject
            (
                "k",
                runTime.timeName(),
                mesh,
                IOobject::MUST_READ,
                IOobject::AUTO_WRITE
            ),
            mesh
        );
    }

I put this field initialization together with pressure and velocity into createFields.H and call it from the main program with #include.

So far no magic. In the main program I check the variable kPresent and can determine weather the file was read or not. For example like this:

Code:

if (kPresent == 1)
    {
        surfaceScalarField ks = fvc::interpolate(k);
    }

I'm doing this if-check at different positions inside the code and this one is the first appearing after including createFields.H.

The problem is that the lines within every if-condition containing k give me trouble when running wmake. In this case:

Code:

error: ‘k’ was not declared in this scope
Why is it not declared? Shouldn't the code know it from createFields.H?
Or is there a problem because k is actually declared inside a
if (kHeader.headerOk()){}-bracket and therefore is not know to the "outside world"?

Any ideas? Have a nice day!

niklas October 21, 2009 06:20

something like this maybe...

Code:

    IOobject kHeader
    (
        "k",
        runTime.timeName(),
        mesh,
        IOobject::NO_READ
    );

    volScalarField* kPointer;
    bool kExist = false;

    if (kHeader.headerOk())
    {
        kExist = true;
        Info<< "Reading k.\n" << endl;

        kPointer = new volScalarField
        (
            IOobject
            (
                "k",
                runTime.timeName(),
                mesh,
                IOobject::MUST_READ,
                IOobject::AUTO_WRITE
            ),
            mesh
        );
    }

    if (kExist)
    {
        surfaceScalarField ks = fvc::interpolate(*kPointer);
    }


F42 August 16, 2023 05:08

In case someone reads this:
The syntax changed for newer OF versions.


Code:



if(MyHeader.typeHeaderOk<volScalarField>(true))       
{
do something
 }


 else
{
do something else
}

worked for me.


All times are GMT -4. The time now is 11:58.