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/)
-   -   Writing data to a file (https://www.cfd-online.com/Forums/openfoam-programming-development/156837-writing-data-file.html)

kcn July 14, 2015 02:11

Writing data to a file
 
Hello,

I modified a solver to calculate a scalar coefficient which I need to compare with some experimental data.

This coefficient is not a scalar field, a simple scalar for each time value.

My problem is how shall I write this scalar to some text file along with time value? Some thing like:

(time scalar value)
(0 0 )
(0.1 0.125 )
(0.2 0.137 )

etc?

Or some alternative form is also fine. All I need to write is coefficient and time.

Can some one please help?

hk318i July 14, 2015 10:05

I believe this question was answered before in this forum, here is a short answer

Code:

#include "OFstream.H"

    fileName name = ("yorFileName");
    OFstream OS(name);
    if (Pstream::master())
    {
        if(OS.opened())
      {
            OS << runTime.value() << tab << scalarValue << endl;
        }
    }

You can use space instead of tab and could add "(" and ")". It works like Info stream.

Asghari_M July 15, 2015 04:32

Hello Hassan and Kcn ;
Should we use OFstream or IOdictionary?
In which part of OpenFoam code, users should add above your code lines?
Thanks for any answer.

hk318i July 15, 2015 05:19

Quote:

Originally Posted by Asghari_M (Post 555523)
Hello Hassan and Kcn ;
Should we use OFstream or IOdictionary?
In which part of OpenFoam code, users should add above your code lines?
Thanks for any answer.

It depends on your needs. for example in OF forces library OFstreams are used because the library requires writing every time step. IOdictionary are useful if in case of OF writing fields or object. It is generally writes when time.write() reached the writing criteria.

You use this code anywhere based on your code layout and the limitations of OFstreams.
Generally for solvers, as per the original question, you can declare the OFstream before the time loop then use the OFstream object anywhere in your code in the same way as using Info or cout.

Asghari_M July 18, 2015 04:53

Quote:

Originally Posted by hk318i (Post 555539)
It depends on your needs. for example in OF forces library OFstreams are used because the library requires writing every time step. IOdictionary are useful if in case of OF writing fields or object. It is generally writes when time.write() reached the writing criteria.

You use this code anywhere based on your code layout and the limitations of OFstreams.
Generally for solvers, as per the original question, you can declare the OFstream before the time loop then use the OFstream object anywhere in your code in the same way as using Info or cout.

Hello Hassan;
Really, I have a problem which I want to know if I have to use OFstream or IOdictionary.
Suppose, There is an inlet x-axis velocity as boundary condition in my problem.
I'm going to save the flow field for four different inlet velocity values.
These four inlet velocities have been specified according to the following expression in a vector:
A={1, 2, 3.5, 4.2}.
Therefore, I defined boundary condition as follows:
Code:

inlet
{
type codedFixedValue;
value $internalField;
redirectType ramp;
code
#{
# How to read A[i] from main C++ program ( stated at next code)? Should I use IOdictionary or OFstream?
(*this)==vector(A(i),0,0);
#};
}

Now, what I need is running OF into a loop (Main program) as follows:
Code:

#start of Main program
vector<double> A(4);
A[0]=1;A[1]=2;A[2]=3.5;A[3]=4.2;
for (int i = 0; i < 4; ++i)
{
# How to run OF program into a loop with A[i] in this line?
# How to save steady state flow in the separated folder for every inlet velocity in this line?

}
#end of main program

I asked my questions in above command lines with red color.
Thanks for any kind attention &answer.

hk318i July 18, 2015 07:23

Hello Mehdi,

I haven't the full answer for your questions but I would like to highlight few points;
  • Regarding the first point, I have limited experience with codeStream in this area but based on my understanding you cannot access a variable A from the solver scope in BC scope unless it could be accessed through the object registry using look-up.
  • Transfer information between different parts of your code isn't a good programming practice because it isn't efficient (slower than reading from memory).
  • Your problem isn't entirely clear to me, is A vector constant or variable? If constant, you can define A in U file, then use dict.lookup("A") inside your codeStream as scalarField
    Code:

    A (1, 2, 3.5, 4.2);
  • If A is variable depends on flow filed parameters and time, I would recommend implementing new BC based on fixed value BC OR you can change the BC value from your solver (less recommend).
  • In OF language vector is a fixed length list of size three. It is a vector in three-dimensional space. In your main program you are using the std::vector<double> which is in OF language scalarField of size four. It is preferable to use OF library over the standard c++ one.
  • For writing A in different files and folders, you have to declare OFstream for each inlet with different fileName then write inside the loop. Pleas note it is a minimal example and it will write over the existing files, therefore you have to rename it before restarting.

    Code:

    #include "OFstream.H"
    #include "OSspecific.H" // for mkDir

        label size = 4;
        List<fileName> names(size); // files names and paths list
        PtrList<OFstream> os(size); // pointer list to OFstream

        // initialization 
        forAll(names, i)
        {
            names[i] = ("folder_"+ Foam::name(i))/("file_"+Foam::name(i)+".dat");
            os.set(i, new OFstream(names[i]));
            mkDir(names[i].path()); // create folders
        }



    scalarField A(size,0.0); // size four with zero elements
    //loop which is equal to standard for-loop in c++
    forAll(A, i)
    {
        A[i] = i; //assign as value for each element
          // check files and the master processor for writing
          if(os[i].opened() && Pstream::master())
          {
              os[i] << A[i] << endl;
          }
          else
          {
            // stop the code if the files haven't opened
              FatalError                               
                  << "files aren't open" << nl
                  << exit(FatalError);     
          } 
    }


I hope that my comments will be useful for your case and kindly notice that these are just general recommendations you shouldn't consider them as the only solution or a black and white guidelines. For example you will find that sometimes is essential to use the standard for-loop and OF source code has plenty of such cases.

Asghari_M July 19, 2015 05:29

Hello Hassan,

First of all, I should describe that in my case , every member of vector(A) is corresponding with a inlet velocity that is in X-axis direction (Ux).
Suppose, I need to gain flow field for t=10 s.

I don't need transient results up to 10s and I'd like to compare flow fields corresponding every inlet velocity with together in final time (t=10s).

There are two ways for this object explained as follows:
1-Running OF by run command in Ubuntu for every Ux with considering fix value for inlet boundary condition.
Then comparing results and plotting graphs for every Ux (Vector A).

2- Altogether, Writing a code to run OF within a loop calling OF 2.3.1 and calling every Ux=A(i) and saving 10s results for every Ux in a separated folder.
In this case, calling OF within loop is an important issue. In my belief, this way is faster than first option.

I selected second option. Obviously, for option 2, Wmake command have to be executed after code writing until code be executable.
How can I do this case ? What are general guidelines for wring a code according to the way (option)2 ?
Thanks,

hk318i July 19, 2015 05:46

As I understand, you want to run you solver with four different inlet conditions for Ux and stop and save the results after 10s. Additionally you want to run these for cases automatically.
I would suggest in that case to write bash script (like Allrun in OF) to loop over the different cases and you can change the BC using sed command. Also you can have a look on pyFoam maybe it could do the job for you.

Asghari_M July 19, 2015 12:21

Quote:

Originally Posted by hk318i (Post 556020)
As I understand, you want to run you solver with four different inlet conditions for Ux and stop and save the results after 10s. Additionally you want to run these for cases automatically.
I would suggest in that case to write bash script (like Allrun in OF) to loop over the different cases and you can change the BC using sed command. Also you can have a look on pyFoam maybe it could do the job for you.

Yes, it is precisely the case I should do.
I don't know great things about bash scripting.
For example, how can I transfer vector/matrices values between inlet boundary & basch script?
For example, I defined inlet boundary in blockMeshdict as follows:
Code:

inlet
{
type codedFixedValue;
value $internalField;
redirectType ramp;
code
#{
# How to read A[i] from main bash scripting code presented as follows?
(*this)==vector(A(i),0,0);
#};
 
}

And, bash script Allrun code as follows:
Code:

# Is this expression correct here?---> A={1, 2, 3.5, 4.2}
# How create folders here for every Ux?

for i =1 to 4
do
  runApplication $(getApplication)
done

How should I write vector A with four Ux components in bash script and then transfer it to inlet boundary in blockMesh?
Also, I tried to use PyFoam. However, after installing PyFoam, I had some troubles with a simple tutorial that I post it at following post:
http://www.cfd-online.com/Forums/ope...-problems.html
Again, I asked my questions with red color at above codes.
Many thanks for your attentions.

hk318i July 19, 2015 12:46

I really cannot help with pyFoam because I don't use it but I read many times on this forum how it could help solving such problems. I think even basic python script could solve your problem.

For bash script, it should be straight forward to create and copy folder because it works exactly like working from the terminal. Your for loop syntax is right, for more options see;
http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-7.html

Also, you will need to modify the velocity BC from your bash script which could be done using sed see;
http://stackoverflow.com/questions/5...ork-it-empties

I hope these hints could be useful because I have limited experience with bash scripting in general.

Asghari_M July 20, 2015 16:41

Hello Hassan,

Thank you very much for your attentions & advises during this discussion.

Although, I have many problems with reading and writing files/data/vectors into OF and vise versa operation yet that I will probably have to post them in next treads and I welcome you to take part in the my next discussion soon.

Sincerely.
M.Asghari

Aaron_L April 17, 2016 10:02

Quote:

Originally Posted by hk318i (Post 555408)
I believe this question was answered before in this forum, here is a short answer

Code:

#include "OFstream.H"

    fileName name = ("yorFileName");
    OFstream OS(name);
    if (Pstream::master())
    {
        if(OS.opened())
      {
            OS << runTime.value() << tab << scalarValue << endl;
        }
    }

You can use space instead of tab and could add "(" and ")". It works like Info stream.

Hi, Hassan,
I use OF2.3.1 version, why I use this expression or only use OFstream.H head file
#include "OFstream.H"
show this errors? can you provide some suggestion?
/usr/include/c++/4.8/bits/codecvt.h: In function ‘int main(int, char**)’:
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected ‘=’ before ‘__attribute__’
namespace std _GLIBCXX_VISIBILITY(default)
^
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected identifier before ‘__attribute__’
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected ‘;’ before ‘__attribute__’
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected primary-expression before ‘__attribute__’
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected ‘;’ before ‘__attribute__’

Best Reards,
Aaron

hk318i April 17, 2016 10:48

Hello Aaron,

I don't fully understand your question. Could you please include the code which gives this error?
I'm sure that this problem isn't related to OF version because I used this class many times under diffrent versions.

Bw,
Hassan Kassem


Quote:

Originally Posted by Aaron_L (Post 595444)
Hi, Hassan,
I use OF2.3.1 version, why I use this expression or only use OFstream.H head file
#include "OFstream.H"
show this errors? can you provide some suggestion?
/usr/include/c++/4.8/bits/codecvt.h: In function ‘int main(int, char**)’:
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected ‘=’ before ‘__attribute__’
namespace std _GLIBCXX_VISIBILITY(default)
^
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected identifier before ‘__attribute__’
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected ‘;’ before ‘__attribute__’
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected primary-expression before ‘__attribute__’
/usr/include/c++/4.8/bits/codecvt.h:41:15: error: expected ‘;’ before ‘__attribute__’

Best Reards,
Aaron


wangziyang March 21, 2021 21:50

How can I avoid overwritting its old time value ?
 
Quote:

Originally Posted by hk318i (Post 555408)
I believe this question was answered before in this forum, here is a short answer

Code:

#include "OFstream.H"

    fileName name = ("yorFileName");
    OFstream OS(name);
    if (Pstream::master())
    {
        if(OS.opened())
      {
            OS << runTime.value() << tab << scalarValue << endl;
        }
    }

You can use space instead of tab and could add "(" and ")". It works like Info stream.

The code works well in my own class, but in the "yourFileName" file, the output scalar over writes on its old time value.

How can i solve this problem?

best wishes

ziyang

Shah Akib Sarwar November 19, 2022 14:26

Quote:

Originally Posted by wangziyang (Post 799449)
The code works well in my own class, but in the "yourFileName" file, the output scalar over writes on its old time value.

How can i solve this problem?

best wishes

ziyang


Did you ever solve this problem? I am facing the same issue.


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