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/)
-   -   using fieldAverage library to average postprocessing (https://www.cfd-online.com/Forums/openfoam-programming-development/70396-using-fieldaverage-library-average-postprocessing.html)

eelcovv November 23, 2009 06:05

using fieldAverage library to average postprocessing
 
Dear programming experts,

I am stuggelling with the following: I want to obtain the average of the fields already create in the time directories (i.e., during postprocessing).

During runtime, this can be done via the functions in the controlDict by adding libfieldFunctionObjects.so

No I want to do the same as a postprocessing step.

My starting point was the postChannel application, that loops over the fields and collaps the field data that is assemed to by homogeneous. This tools requires Umean to be present. I want to create the Umean fields by a similar postprocessing tool called for instance postAverage

This new tool (if it has been developped yet, please tell me) should read the controlDict dictionary, and than read the averaging information

I took out all the functionality of postChannel (the collapsing of the fields) and I changed the line

Code:


// For each time step read all fields
//    forAll(timeDirs, timeI)
    while(runTime.loop())

with the while runTime.loop construction, the controlDict is read and therefore the library is included.

However, if I run this I get the complaint From function Foam::fieldAverage::initialize()
in file fieldAverage/fieldAverage/fieldAverage.C at line 102.

Of course this makes sence, because I do not do an explicit creation of the fields.

Now the simple solution would be: explicity create the field U in the postAverage.

However, this would make the utility less generic. I want it automatically to create the field that are defined in controlDict function fieldAverage.

My idea was to include the fieldobject and reuse the code for creating fieldAverageItem. Unfortunately, I can not add or reuse the library in an external code, and therefore I can not reuse this functionality.

I am relatively new to C++, but I that the power of it lies in reusing code, therefore I am quite sure this must be possible (I moreover, is desirable)

Hopefully there is an OpenFoam programming expert out there who could give me a hint how to do tackle this problem.

Or, which would be even better: is there somebody of has written a postprocessing utility to do the averaging of the time steps over a certain time range?

Any hints very much appreciated!

Regards,

Eelco

eelcovv November 24, 2009 07:49

well,

It seems there are not many users dealing with the same issue.

Let me refrase the my quest:

I want to write a program that loops of the time directories, reads the fieds, and than writes an average field in the last directory.


In this way, averaging can be done after the run as a postprocessing step, so that the first time steps can easily be left out if the start up is not stationary yet.

Ideally, I would like to use for instance the existing foamCalc utility and combine that the the fieldAverage library so that during the loop the controlDict is used to do the job. I dug into the code, but can not find how I should modify it. I am too inexperience in C++, so I leave this to the real programming experts maybe with the next release (I can imagine that I am not the only user who'd like to have this functionality)

Today I have spend my whole day digging into all the utilities to try to come up with my own solution. It is an ugly solution, in terms of proper C++ programming, but it is a start, and it works!. I am adding the code here. I would appreciate very much if somebody could comment on the most ugly construction I have used (see comments in the code). Probably there are better ways, but I just can not find how at the moment

Code:

/*---------------------------------------------------------------------------*\
  =========                |
  \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox
  \\    /  O peration    |
    \\  /    A nd          | Copyright (C) 1991-2009 OpenCFD Ltd.
    \\/    M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM; if not, write to the Free Software Foundation,
    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Application
    foamTimeAverage

Eelco van Vliet

Version:
very first piece of ugly c++ code, but it works!

Description
    Calculates the time average  of the specified scalar field over the specified time range.

\*---------------------------------------------------------------------------*/

#include "fvCFD.H"
#include "argList.H"
#include "timeSelector.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:

int main(int argc, char *argv[])
{

    Foam::timeSelector::addOptions();
    Foam::argList::validArgs.append("fieldName");

    // the order of the calls below is important!

    // defines the first directory
#  include "setRootCase.H"
    // defines time stuff
#  include "createTime.H"

    // get filename from command line
    word fieldName(args.additionalArgs()[0]);

    // create list of time steps based on the -time argument
    instantList timeDirs = timeSelector::select0(runTime, args);

    // set the runTime at the first time step of the given range
    runTime.setTime(timeDirs[0], 0);

    // now: create mesh based on the first time step of the given range
#  include "createMesh.H"


    // read first the field into a dummy variable, otherwise the write
    // statement at the bottom used fieldName to over write the original field.
    // How can I used change the filename instead of this trick?
    Info<< "    Create mean field" << nl<<endl;
    volScalarField dummy
    (
    IOobject
    (
        fieldName,
        runTime.timeName(),
        mesh,
        IOobject::MUST_READ
      ),
    mesh
    );

   
    // create the new file name with the _mean extension
    const word EXT_MEAN = "_mean";
    const word meanFieldName=fieldName+EXT_MEAN;

    // create the field with the meanFieldName based on the dummy so that all
    // the properties are the same. Probably can be done much more efficient
    volScalarField mean
    (
    IOobject
    (
        meanFieldName,
        runTime.timeName(),
        mesh,
        IOobject::NO_READ
      ),
    dummy
    );

    // and now initialise at zero. Much better would be to do this right away.
    // How can that be done?
    mean*=0;

    // start the counter out 0;
    int nfield=0;

    // loop over the time directories
    forAll(timeDirs, timeI)
    {
        // set to the current time directory
        runTime.setTime(timeDirs[timeI], timeI);

        // give some information
        Info<< "timeI: "<< timeI<< " Time = " << runTime.timeName() << endl;

        // read the header field 'fieldName'
        IOobject fieldHeader
        (
            fieldName,
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ
        );

        // Check field exists
        if (fieldHeader.headerOk())
        {
            // the mesh exists, read the data
            mesh.readUpdate();

            if (fieldHeader.headerClassName() == "volScalarField")
            {
              // the data is volScalar data -> add the field to the mean
              Info<< "    Reading volScalarField " << nfield << " " << fieldName << endl;
              volScalarField field(fieldHeader, mesh);
              mean+=field;
              nfield++;
            }
            else
            {
                FatalError
                    << "Only possible to average volScalarFields "
                    << nl << exit(FatalError);
            }
        }
        else
        {
            Info<< "    No field " << fieldName << endl;
        }

        Info<< endl;
    }


    // devide by the number of added fields
    if(nfield>0){
      Info<< "number of fields added: "<< nfield << endl;
      mean/=nfield;
    }

    Info<< "writing to file "  << endl;
    mean.write();

    Info<< "End\n" << endl;

    return 0;
}

// ************************************************************************* //

It is all based on a combination of foamCalc and the vorticity utility. Hopefully somebody can make suggestions to get this a cleaner C++ code. However, it does exactly what I want!

for instance

foamTimeAverage Ux -time 300:

gives the time average Ux_mean field from the time steps 300 to the end.
Please free to use it or come with improvements

Regards

Eelco

eelcovv November 26, 2009 00:39

1 Attachment(s)
If anybody is interested in post-processing field averaging (I can hardly imagine nobody ever needs it), here an improved version thanks to a hint of Bernard Gschaider I was able to force to read the fieldAverage library in the controlDict using the runTime.functionObjects().execute() statement. In this way, all the functionality of the library is available.

The code of postAverage.C looks like
Code:

/*---------------------------------------------------------------------------*\
  =========                |
  \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox
  \\    /  O peration    |
    \\  /    A nd          | Copyright (C) 1991-2009 OpenCFD Ltd.
    \\/    M anipulation  |
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

    OpenFOAM is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2 of the License, or (at your
    option) any later version.

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    You should have received a copy of the GNU General Public License
    along with OpenFOAM; if not, write to the Free Software Foundation,
    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

Application
    postAverage

Eelco van Vliet

Description
    Post-processes data from flow calculations
    For each time: calculates the time average of a sequence of fields and
    writes time time average in the directory



\*---------------------------------------------------------------------------*/

#include "fvCFD.H"
//#include "fieldAverageFunctionObject.H"
//#include "dictionary.H"
//#include "IFstream.H"
//#include "OFstream.H"

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//  Main program:

int main(int argc, char *argv[])
{
    argList::noParallel();
    timeSelector::addOptions();

#  include "setRootCase.H"
#  include "createTime.H"

    instantList timeDirs = timeSelector::select0(runTime, args);
    runTime.setTime(timeDirs[0], 0);
#  include "createMesh.H"

  // what is required to initilise only the field in fieldAverage ?
// dictionary dict(IFstream("controlDict")());
// fieldAverageFunctionObject avefield() ;
// fieldAverage bla avefield.read() ;
// avefield.fieldAverage(dict);

    forAll(timeDirs, timeI)
    {
      runTime.setTime(timeDirs[timeI], timeI);
      Info<< "Adding fields for time " << runTime.timeName() << endl;
#      include "createFields.H"

      // Average fields over channel down to a line
      runTime.functionObjects().execute();
    }

    Info<< "\nEnd" << endl;


    return 0;
}

// ************************************************************************* //

and requires an include file createFields.H to read the field you want to average, for example
Code:

    Info<< "Reading field p\n" << endl;
    volScalarField p
    (
        IOobject
        (
            "p",
            runTime.timeName(),
            mesh,
            IOobject::READ_IF_PRESENT,
            IOobject::NO_WRITE
        ),
        mesh
    );

    Info<< "Reading field U\n" << endl;
    volVectorField U
    (
        IOobject
        (
            "U",
            runTime.timeName(),
            mesh,
            IOobject::READ_IF_PRESENT,
            IOobject::NO_WRITE
        ),
        mesh
    );

Using this routine allows you to read the given fields over a given time range and average them as a post-processing step, like

postAverage -time:300

The field averaging parameters should be given in the controlDict. The only important thing is that the outputControl is set on timeStep, e.g
Code:

/*--------------------------------*- C++ -*----------------------------------*\
| =========                |                                                |
| \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox          |
|  \\    /  O peration    | Version:  1.6                                  |
|  \\  /    A nd          | Web:      www.OpenFOAM.org                      |
|    \\/    M anipulation  |                                                |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version    2.0;
    format      ascii;
    class      dictionary;
    location    "system";
    object      controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

application    channelFoam;

startFrom      startTime;

startTime      0;

stopAt          endTime;

endTime        700;

deltaT          0.01;

writeControl    adjustableRunTime;

writeInterval  100;

purgeWrite      0;

writeFormat    ascii;

writePrecision  6;

writeCompression compressed;

timeFormat      general;

timePrecision  6;

runTimeModifiable yes;

adjustTimeStep yes;

maxco            0.2;

maxDeltaT        1;

functions
{
    fieldAverage1
    {
        type            fieldAverage;
        functionObjectLibs ( "libfieldFunctionObjects.so" );
        enabled        true;
          cleanRestart        true;
        outputControl  timeStep;
//        outputControl  outputTime;
        outputInterval  1000;
        fields
        (
            U
            {
                mean        on;
                prime2Mean  on;
                base        time;
            }

            p
            {
                mean        on;
                prime2Mean  on;
                base        time;
            }
        );
    }
}

I have one question, hopefully somebody is able to answer it. In the current code, the fields you want to average are given in createFields. Once you have compiled postAverage the code will always try to read all these fields, even if you only want to average say the velocity field. Much better, of course, would be if the fields to be averaged are read from the controlDict in advance, and the reading takes place based on the fields defined in the controlDict. I am sure that is possible by using the loop forAll(faItems_, fieldI) as can be found in the fieldAverage library. I have no idea, however, how to do this. I should probably define an instance of the class fieldAverage and use the method to read the dictionary, and then apply the loop to read the appropriate fields. I am unfortunately too inexperienced in C++, so I hope that somebody can a hint.

Thanks

Eelco


ps:
the code is attached below

wen December 21, 2009 06:55

I'm searching for this utility function. I'll try it firstly.

chantre March 18, 2011 11:26

Hi Eelco,
thanks a lot for this very helpful tool

/Andreas

sam1364 January 6, 2012 12:55

Hi guys

I want to do field averaging of Reynolds stress tensor (R) during running my code. It seems that the fieldaveraging library do the averaging just for U and P. How can I do the same thing for R?
I would be so appreciated if you can help me

Thanks

iatrid January 10, 2012 08:16

Dear eelcovv,

<If anybody is interested in post-processing field averaging (I can hardly imagine nobody ever needs it), here an improved version thanks to a hint of Bernard <Gschaider I was able to force to read the fieldAverage library in the controlDict using the runTime.functionObjects().execute() statement. In this way, all the <functionality of the library is available. >

Thank you very much for the very important code you supplied here. But when I execute the code postAverage (including the code i added in the system/controDict file), i realize that nothing changed. Can you give me a hint? Should a new variable be generated Umean or the averaged calculation is still saved as U?

thank you once more!
Alex

eelcovv February 24, 2012 05:50

Sorry for the late reply, I only see this post now.

Please make sure that you have in you field average dictionary

outputControl outputTime;

and make sure that you write interval is equal to the write interval of the original simulation. If that is not the case, nothing is written indeed.

Good luck

Regards
eelco

iatrid March 6, 2012 02:04

Quote:

Originally Posted by eelcovv (Post 346104)
Sorry for the late reply, I only see this post now.

Please make sure that you have in you field average dictionary

outputControl outputTime;

and make sure that you write interval is equal to the write interval of the original simulation. If that is not the case, nothing is written indeed.

Good luck

Regards
eelco

thank you very much. You were very helpfull!!

mirel May 9, 2012 03:13

Thank you!
 
This tool is very helpful indeed. Thank you very much, Eelcovv!!
:)

buct11019 May 9, 2012 22:46

hi, the unility is very helpful, and I want ask what is UPrime2mean, the computational formula of it and transient k is the same, but do they the same in real physical meanings?

eelcovv May 13, 2012 13:09

My utility just makes a call to the averaging libraries developed by Bernard sgnaider, so don't pin me on it. But I think uprime2mean does the following. The velocity in general can be writen as U=<U>+u', where <...> indicates the ensemble average and u' is the deviation on it. The purpose at the start of the calculation is to calculate <u'^2>=<(U-<U>)^2>, i.e. the <u'^2> mean which is indeed related to k. During the run, however, <U> is not known, because you still need to average it in time. Therefore, it does not give you <u'^2>, but <U^2>. Both of them are related according to <u'^2>=<(U-<U>)^2>=<U^2> - <2*U*<U>> + <U>^2 = <U^2>-<U>^2. In other words, you can obtain the <u'^2> by subtracting the Umean squared from the Uprime2mean

Hanzo June 21, 2012 05:08

Quote:

Originally Posted by eelcovv (Post 237751)
If anybody is interested in post-processing field averaging (I can hardly imagine nobody ever needs it)

Thank you for the code . Yeah, I also believe that this feature is well needed and also wonder why there is not such a tool in OpenFoam.

Could you explain how it is determined where the averaged field is written to? The code iterates over all my time steps but the effect of setting outputInterval to 2, 3, 10, 100, 1000 does not yield my desired result. (which is: save in every 2nd time step folder, every 3rd, 10th, 100th, 1000th)

Basically, I just want to have the averaged field written into the last timestep folder.

eelcovv October 2, 2012 03:30

Hi hanzo,

without testing it I would say play with

writeControl adjustableRuntTime;

writeInterval 100;

Where 100 now is not a interval in iterations but in time step and take you last time step only. The averaging is done by fieldAverage functionobject list, so the setting is control by this lib
good luck

atmcfd January 18, 2013 01:20

Quote:

Originally Posted by eelcovv (Post 384459)
Hi hanzo,

without testing it I would say play with

writeControl adjustableRuntTime;

writeInterval 100;

Where 100 now is not a interval in iterations but in time step and take you last time step only. The averaging is done by fieldAverage functionobject list, so the setting is control by this lib
good luck

Hi Eelco,


Thanks for the code. I tried running it many times with the instructions in this thread - but the code reads the fields at all the times and doesnt save the mean data anywhere. Am I missing something?

Here is my controldict file:

Code:


/*--------------------------------*- C++ -*----------------------------------*\
| =========                |                                                |
| \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox          |
|  \\    /  O peration    | Version:  2.1.1                                |
|  \\  /    A nd          | Web:      www.OpenFOAM.org                      |
|    \\/    M anipulation  |                                                |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version    2.0;
    format      ascii;
    class      dictionary;
    location    "system";
    object      controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

application    channelFoam;

startFrom      latestTime;

startTime      0;

stopAt          endTime;

endTime        1.012;

deltaT          0.0001;

writeControl    timeStep;

writeInterval  100;

purgeWrite      0;

writeFormat    ascii;

writePrecision  6;

writeCompression off;

timeFormat      general;

timePrecision  6;

runTimeModifiable true;               

// adjustTimeStep yes;

// maxCo 0.3;

// maxDeltaT 0.0001;

functions
{
    probes
    {
        type            probes;
        functionObjectLibs ("libsampling.so");
        enabled        true;
        outputControl  timeStep;
        outputInterval  1;

        fields
        (
            p
            U
            nuSgs
            nuTilda
            k
            B
        );

        probeLocations
        (
            ( 0.005 1.2 0.5 )
            ( 0.005 1.2 1 )
            ( 0.005 1.2 1.5 )
            ( 0.005 1.2 2 )
        );

 fieldAverage1
    {
    type fieldAverage;
    functionObjectLibs ( "libfieldFunctionObjects.so" );
    enabled true;
    outputControl outputTime;
    outputInterval  100;
    fields
    (
      U
      {
      mean on;
      prime2Mean on;
      base time;
      }

      p
      {
      mean on;
      prime2Mean on;
      base time;
      }
      );
      }
    }

Can you please tell me what is wrong here? Is this declaration in Controldict all I need or do I need any other file too?
Thanks a lot. I have a lot of data to be averaged :confused:

Hanzo January 18, 2013 22:16

Quote:

Originally Posted by atmcfd (Post 402569)
Hi Eelco,


Thanks for the code. I tried running it many times with the instructions in this thread - but the code reads the fields at all the times and doesnt save the mean data anywhere. Am I missing something?

Here is my controldict file:

Well, the code works, I can confirm that. But I also realised some strange (or not straightforward for me to understand) behaviour of how the output is written. At the moment I do the following:

Set
outputInterval 1;
or
outputInterval 2;

in fieldAverage1.
Then output is written to every / every second data folder. Then I copy the Mean files from the last timestep to some other place. The next step is to erase all *Mean files in the data folders.

When you have to do it only once or twice, I think it is okay to live with it.

Nucleophobe March 21, 2013 11:45

execFlowFunctionObjects
 
Thank you very much for this tool, it works well for my purposes.

I have a question however. Can the same thing be done with the 'execFlowFunctionObjects' utility? Is there an advantage to this code, or do they work about the same?

If anyone knows the clarification would help. Thanks!

jiejie April 2, 2013 20:43

Hi eelcovv

Thank you very much for the code, which is really handy and useful.

Quote:

Originally Posted by Hanzo (Post 402793)
Then output is written to every / every second data folder. Then I copy the Mean files from the last timestep to some other place. The next step is to erase all *Mean files in the data folders.

When you have to do it only once or twice, I think it is okay to live with it.

As Hanzo mentioned, I just wonder whether it is possible for the code to write the Mean field at the very last time step? I am having a bunch of data (about 50,000 fileld files), it will take a lot space to write the Mean field out for every time step.

Thanks

jiejie

jiejie April 3, 2013 23:57

Quote:

Originally Posted by eelcovv (Post 360815)
Therefore, it does not give you <u'^2>, but <U^2>. ... In other words, you can obtain the <u'^2> by subtracting the Umean squared from the Uprime2mean

Hi eelcovv

Just got a quick question regarding to calculating <u'^2>. There are 6 values in the UPrime2Mean, which are xx,yy,zz,xy,yz,xz. Since the postAverage UPrime2Mean gives <U^2> instead of <U'^2>. Should I use the first 3 columns from postAverage's UPrime2Mean takes away UMean^2 to get the <U'^2>?

Assume the above was correct, I calculated the <U'^2>. However, I found it looks almost the same as UMean instead?

My other question is whether the UPrime2Mean is the variance of the velocity field? ( Please see this link: http://www.cfd-online.com/Forums/ope...n-etc-les.html)

Many thanks.

jiejie

Hanzo April 4, 2013 06:37

Quote:

Originally Posted by jiejie (Post 418214)
Hi eelcovv

Just got a quick question regarding to calculating <u'^2>. There are 6 values in the UPrime2Mean, which are xx,yy,zz,xy,yz,xz. Since the postAverage UPrime2Mean gives <U^2> instead of <U'^2>. Should I use the first 3 columns from postAverage's UPrime2Mean takes away UMean^2 to get the <U'^2>?

Assume the above was correct, I calculated the <U'^2>. However, I found it looks almost the same as UMean instead?

If my calculations are right then UPrime2Mean should exactly be what it says:
U-prime, squared and averaged = <u'^2>. To check this, you can compute u' using U and <U> , calculate u'^2 and average it manually. I did this for a series of data sets and when I compared UPrime2Mean with manually generated <u'^2> they turned out to be the same.

Another hint is the magnitude. In my computations, the biggest components of UMean_X are around 0.97 and UPrime2Mean_XX of 0.0025.
UPrime2Mean cannot be U^2

jiejie April 4, 2013 07:43

Quote:

Originally Posted by Hanzo (Post 418295)
If my calculations are right then UPrime2Mean should exactly be what it says:
U-prime, squared and averaged = <u'^2>. To check this, you can compute u' using U and <U> , calculate u'^2 and average it manually. I did this for a series of data sets and when I compared UPrime2Mean with manually generated <u'^2> they turned out to be the same.

Another hint is the magnitude. In my computations, the biggest components of UMean_X are around 0.97 and UPrime2Mean_XX of 0.0025.
UPrime2Mean cannot be U^2

Hi Hanzo

Thanks for your quick reply. I was not saying UPrime2Mean is U^2. I calculate the UPrime and found it is the same as sqrt(UPrime2Mean). I got confused as eelcovv hinted " you can obtain the <u'^2> by subtracting the Umean squared from the Uprime2mean". I am not trying to offend anyone but find the right meaning of UPrime2Mean.

Thanks

jiejie

Hanzo April 4, 2013 08:47

Quote:

Originally Posted by jiejie (Post 418313)
I am not trying to offend anyone but find the right meaning of UPrime2Mean.

I am sorry if my comment let you feel like this. I did not want to say that you are offending anyone. It's just my raw english :o I am also highly interested in the correct meaning of UPrime2Mean.

Quote:

Originally Posted by jiejie (Post 418313)
Hi Hanzo

Thanks for your quick reply. I was not saying UPrime2Mean is U^2. I calculate the UPrime and found it is the same as sqrt(UPrime2Mean). I got confused as eelcovv hinted " you can obtain the <u'^2> by subtracting the Umean squared from the Uprime2mean".

How did you compute UPrime? Did you take U - UMean and averaged this over several time steps? Or for a single realization only?
Averaging this would give <u'> (should be a value close to zero, right?). And then you compared to sqrt( UPrime2Mean ) (which is related to the rms value sqrt(<u'^2>) according to my understanding).
If you are right then UPrime2Mean gives <u'>^2.

Could you describe a little bit more in detail what you calculated?
I really hope that UPrime2Mean_XX corresponds to <u_x'^2>,
UPrime2Mean_YY to <u_y'^2> and so on. If not I have to recheck quite some of my results :D

jiejie April 4, 2013 08:58

Quote:

Originally Posted by Hanzo (Post 418332)
I am sorry if my comment let you feel like this. I did not want to say that you are offending anyone. It's just my raw english :o I am also highly interested in the correct meaning of UPrime2Mean.

Could you describe a little bit more in detail what you calculated?
I really hope that UPrime2Mean_XX corresponds to <u_x'^2>,
UPrime2Mean_YY to <u_y'^2> and so on. If not I have to recheck quite some of my results :D

Hi Hanzo

I thought I might upset eelcovv as I was confused with his hint :D. Anyway, I actually output the flow field for every single time step and use the postprocessing utility sample to probe the velocity at a few locations. Then, I calculate the the veocity RMS by its definition, which should be the UPrime^2. I did this a while ago, I think the RMS value is very close to the sqrt of UPrime2Mean. That's why I am thinking UPrime2Mean is giving the correct result.

jiejie

eelcovv July 22, 2013 16:26

Hi jiejie,

You are correct, my hint in an ealier post is misleading. The uprime2suare is already correct for U^2.
So if you define U(t)=<U>+u'(t) then the uprime2square constains the in this order:

<u'^2> <uv> <uw> <v'^2> <vw> <w'^2>

no need to subtract anything. Forget my remark about that.

If you want to plot for instance the turbulent kinetic energy k over a line sampled from you uprima2square you can just do

plot 'sampledline_with_UPrime2Square' u 1:(0.5*($2+$5+$7))

cheers

snappyHex November 14, 2013 07:03

Hi eelcovv,

Thanks for the utility, it is really helpful!
However I am not getting the results that I would expect.
I have two time directories (0 and 90) and I want to get the average of the U field. Running the application I get the Umean file but the results are not correct,
i.e. U in 0 : (0.1107 -0.0027 0.0006),
U in 90: (0.0036 -0.1216 -0.0004)

and the average I get is: (0.1017 -0.0126 0.0005).

Could you give me any hint of what it can be wrong?
Thanks!

My controlDict:
Code:

/*--------------------------------*- C++ -*----------------------------------*\
| =========                |                                                |
| \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox          |
|  \\    /  O peration    | Version:  2.1.1                                |
|  \\  /    A nd          | Web:      www.OpenFOAM.org                      |
|    \\/    M anipulation  |                                                |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version    2.0;
    format      ascii;
    class      dictionary;
    location    "system";
    object      controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

application    simpleFoam;

startFrom      startTime;

startTime      0;

stopAt          endTime;

endTime        90;

deltaT          1;

writeControl    timeStep;

writeInterval  90;

purgeWrite      0;

writeFormat    ascii;

writePrecision  7;

writeCompression on;

timeFormat      general;

timePrecision  6;

runTimeModifiable true;
functions
{
    fieldAverage1
    {
        type            fieldAverage;
        functionObjectLibs ( "libfieldFunctionObjects.so" );
        enabled        true;
        cleanRestart        true;
        outputControl  timeStep;
  //      outputControl  outputTime;
        outputInterval  1;
        fields
        (
            U
            {
                mean        on;
                prime2Mean  on;
                base        time;
            }

       
        );
    }
}


Nucleophobe January 28, 2014 14:28

1 Attachment(s)
Quote:

Originally Posted by snappyHex (Post 461955)
Hi eelcovv,

Thanks for the utility, it is really helpful!
However I am not getting the results that I would expect.
I have two time directories (0 and 90) and I want to get the average of the U field. Running the application I get the Umean file but the results are not correct,
i.e. U in 0 : (0.1107 -0.0027 0.0006),
U in 90: (0.0036 -0.1216 -0.0004)

and the average I get is: (0.1017 -0.0126 0.0005).

snappyHex,

I know this is an old thread, but I am trying to understand what's going on with the postAverage utility as well. Did you ever resolve the problem?

I tried to replicate your results, but I instead get
(0.075 -0.04233333333 0.0002666666667)
in 90/UMean. Strange.


I tried creating a single-cell mesh with a uniform velocity of (1 0 0) in timestep '0', and a uniform velocity of (2 0 0) in timestep '1'. Rather than a result of (1.5 0 0), I get (1.333333333 0 0)!

I have attached the case for reference (see README file).

Edit: This seems to be the same problem Yann was having:
http://www.cfd-online.com/Forums/ope...tml#post384964

I think the key lies in the 'uniform/time' files saved in each timestep directory; the information in these files (e.g. deltaT) determines how the averaging is performed! Removing all 'uniform' directories via 'rm -r */uniform' (be careful) changes the results for me. However, it's still not quite right.


For now, I am using ParaView's 'Temporal Statistics' filter and saving the resulting data to VTK (Save Data -> .vtm filetype).

Nucleophobe January 29, 2014 15:40

postAverage 'bug' fix
 
All,

EDIT: the original code for postAverage seems to work fine on OpenFOAM/2.2.0/051613. I was having problems with OpenFOAM/2.1.x/071612. If in doubt, check your setup with the case I posted above or something similar.

I have found a solution, but so far it only works if your data is saved at consistent time intervals (1, 2, 3 etc., not 1, 3, 4, 4.5 5.1...).

The utility was counting values from the first timestep twice when computing the average. So, for instance, the average of '1' and '2' was (1 + 1 + 2)/3 = 1.3333 instead of (1 + 2) / 2 = 1.5. This may or may not be a big deal; if you are averaging a lot of data with a small standard deviation, you won't even notice. However, if you are trying to average only a few time directories, it can make a big difference.

I have fixed the problem by subtracting one from the startTime index 'timeI'. You should also clear or move your '(time)/uniform' directories, or else the '(time)/uniform/time' files will mess up the average. Perhaps changing the functionObject options in 'system/controlDict' would make this unnecessary and allow for averaging data saved at inconsistent time intervals, but I have not tried this yet.

Here is my change to postAverage (see bolded line):
Code:

\*---------------------------------------------------------------------------*/

#include "fvCFD.H"

int main(int argc, char *argv[])
{
    argList::noParallel();
    timeSelector::addOptions();

#  include "setRootCase.H"
#  include "createTime.H"

    instantList timeDirs = timeSelector::select0(runTime, args);
    runTime.setTime(timeDirs[0], 0);
#  include "createMesh.H"

    // Cycle through time directories
    forAll(timeDirs, timeI)
    {
      Info<< "Setting startTime index to: " << timeI - 1 << endl;
      // It is important that we set the startTime  index to 'timeI-1' to avoid counting values in the first time directory twice
      runTime.setTime(timeDirs[timeI], timeI - 1);
      Info<< "Adding fields for time " << runTime.timeName() << endl;

#      include "createFields.H"

      runTime.functionObjects().execute();
    }

    Info<< "\nEnd" << endl;


    return 0;
}

// ************************************************************************* //

This is giving me the results I expect. If someone else knows a better way to fix this problem, please chime in!

Good luck,
-Nuc

Cluap September 2, 2015 04:58

1 Attachment(s)
Hi everybody !

Thanks eelcovv for this very usefull tool !

However I am now trying to use it with a dynamic mesh case and I am facing some difficulties.
In order to make it work with a mesh changing over the time I've added #include "dynamicFvMesh.H" in the top of the postAverage.C file, I've switched #include "createMesh.H" to #include "createDynamicFvMesh.H" and I've added the line mesh.readUpdate(); in the time loop.
(see the file attached)

When I run the tool it seems to do the calculations but at the end it gives me completely absurd results.

Anybody knows how to make it work correctly with a dynamic mesh ?

Thanks in advance

manuc August 8, 2016 04:53

Hello

Were you able to write the data only at last time step

pintu0101 May 19, 2017 08:58

unable to run the code
 
sir,
plz tell me how to run the given code and how to get time averaged pressure or velocity for the whole domain in a dat file.

sitajeje July 9, 2017 06:53

The standard fieldAverage utility in OpenFOAM4.0 with the command "simpleFoam -postProcess" can also do this postAverage job.

arashfluid December 24, 2020 04:31

time average over the all time steps stored in the case file
 
Dear friends
I want to calculate the average of a variable like a tau over the time steps saved in the case file, and finally, get a Tau_mean file that is the time-average of all stored time steps in the last time directory. How can I do this with the postAverage tool?

ansab_sindhu May 17, 2022 09:55

Extract Data from field average
 
Hi,

I have stored Tmean from 500 seconds to 1500 seconds using the field average function object. But, in the time directories, I have stored only last 50 time steps using the purge write option in the control dict.

Can I use this utility to extract field (Tmean) from 1000 seconds to 1500 seconds using post processing. Please note that I have time directories stored from 1450 to 1500.

Really appreaite if anyone can comment.


All times are GMT -4. The time now is 04:48.