首发于有所思

OpenFOAM中的fieldaverage

目的是给速度等variable算average.

OpenFOAM: Field averagewww.openfoam.com

The fieldAverage function object calculates and stores ensemble- or time-based field averages, with optional windowing. It is applicable to all field types, i.e. scalar, vector, tensor etc.


ensemble average和time-based field averages都能算.windows可以调.


使用方法是在controlDict里加上一个function,在里面加上fieldAverage的内容.

OpenFOAM/OpenFOAM-2.4.xgithub.com图标
fieldAverage1
{
    type            fieldAverage;
    libs            ("libfieldFunctionObjects.so");

    fields
    (
        <field name 1>
        {
            mean        <yes|no>;
            prime2Mean  <yes|no>;
            base        <time|iter>;


            // Optional entries

            // Averaging window
            window      10;

            // Name of averaging window
            windowName  box1;
        }
        ...
        <field name N>
        {
            mean        <yes|no>;
            prime2Mean  <yes|no>;
            base        <time|iter>;


            // Optional entries

            // Averaging window
            window      5;

            // Name of averaging window
            windowName  box2;
        }
    );


    // Optional entries

    // Clear averaging history on case restart
    restartOnRestart    no;

    // Clear averaging history on case write
    restartOnOutput     no;

    // Clear averaging history on at every `restartPeriod`
    periodicRestart     no;
    restartPeriod       100;
}

注意base分为time和iter两种:

https://github.com/OpenFOAM/OpenFOAM-2.4.x/blob/2b147f41daf9ca07d0fb4c6b0576dc3d10a435f3/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverage.Hgithub.com

根据源文件里的描述:

- base: average over 'time', or 'iteration' (\f$N\f$ in the above)

iter是iteration的意思,应该是steady state的case里没有时间,就用iteration代替算average.


却不知道ensemble average怎么算,估计是算不了.


还有一个问题就是,我在2.4版本的OpenFOAM里选择不同数值的window,我选了20和50两种,但得到的average field却是一模一样的.可能这个版本的代码有问题吧.


查了一下code:

https://github.com/OpenFOAM/OpenFOAM-2.4.x/blob/2b147f41daf9ca07d0fb4c6b0576dc3d10a435f3/src/postProcessing/functionObjects/field/fieldAverage/fieldAverage/fieldAverageTemplates.Cgithub.com
template<class Type1, class Type2>
void Foam::fieldAverage::calculatePrime2MeanFieldType(const label fieldI) const
{
    const word& fieldName = faItems_[fieldI].fieldName();

    if (obr_.foundObject<Type1>(fieldName))
    {
        const Type1& baseField = obr_.lookupObject<Type1>(fieldName);
        const Type1& meanField =
            obr_.lookupObject<Type1>(faItems_[fieldI].meanFieldName());

        Type2& prime2MeanField = const_cast<Type2&>
        (
            obr_.lookupObject<Type2>(faItems_[fieldI].prime2MeanFieldName())
        );

        scalar dt = obr_.time().deltaTValue();
        scalar Dt = totalTime_[fieldI];

        if (faItems_[fieldI].iterBase())
        {
            dt = 1.0;
            Dt = scalar(totalIter_[fieldI]);
        }

        scalar alpha = (Dt - dt)/Dt;
        scalar beta = dt/Dt;

        if (faItems_[fieldI].window() > 0)
        {
            const scalar w = faItems_[fieldI].window();

            if (Dt - dt >= w)
            {
                alpha = (w - dt)/w;
                beta = dt/w;
            }
        }

        prime2MeanField =
            alpha*prime2MeanField
          + beta*sqr(baseField)
          - sqr(meanField);
    }
}

看起来window是用来替代Dt的,当Dt - dt >= w时.那么Dt是什么呢?

scalar Dt = totalTime_[fieldI];

看起来Dt就是总时间数,就是不知道这个总时间数是随时间变化的还是不变的,我觉得应该是变化的.

可以用gdbOF查一下:

陈与论:用GdbOF追踪laplacian函数在OpenFOAM中的定义过程zhuanlan.zhihu.com图标

gdbOF的使用说明见上方链接.

gdb pisoFoam
b fieldAverageTemplates.C:262
r

输出如下,成功定位:

Time = 0.005

Courant Number mean: 0 max: 0
smoothSolver:  Solving for Ux, Initial residual = 1, Final residual = 2.80497e-06, No Iterations 3
smoothSolver:  Solving for Uy, Initial residual = 1, Final residual = 1.70481e-06, No Iterations 3
GAMG:  Solving for p, Initial residual = 1, Final residual = 0.0259767, No Iterations 3
time step continuity errors : sum local = 5.917e-07, global = -4.54949e-21, cumulative = -4.54949e-21
GAMG:  Solving for p, Initial residual = 0.0217357, Final residual = 5.60883e-07, No Iterations 12
time step continuity errors : sum local = 2.91188e-11, global = -1.67924e-21, cumulative = -6.22873e-21
smoothSolver:  Solving for k, Initial residual = 1, Final residual = 1.95397e-06, No Iterations 3
ExecutionTime = 0.05 s  ClockTime = 1 s

fieldAverage fieldAverage1:
    Reading/initialising field UMean
    Reading/initialising field UPrime2Mean

fieldAverage fieldAverage1 output:
    Calculating averages

Breakpoint 1, Foam::fieldAverage::calculatePrime2MeanFieldType<Foam::GeometricField<Foam::Vector<double>, Foam::fvPatchField, Foam::volMesh>, Foam::GeometricField<Foam::SymmTensor<double>, Foam::fvPatchField, Foam::volMesh> > (this=0x8b8e30, fieldI=0) at fieldAverage/fieldAverage/fieldAverageTemplates.C:262
262	        scalar dt = obr_.time().deltaTValue();
(gdb) l
257	        Type2& prime2MeanField = const_cast<Type2&>
258	        (
259	            obr_.lookupObject<Type2>(faItems_[fieldI].prime2MeanFieldName())
260	        );
261	
262	        scalar dt = obr_.time().deltaTValue();
263	        scalar Dt = totalTime_[fieldI];
264	
265	        if (faItems_[fieldI].iterBase())
266	        {
(gdb) 

我们在262行和265行设置断点,让程序输出每个循环后的dt和Dt:

第一个iteration:

(gdb) p dt
$3 = 0.0050000000000000001
(gdb) p Dt
$4 = 0.0050000000000000001
(gdb)

第二个iteration:

(gdb) p dt
$7 = 0.0050000000000000001
(gdb) p Dt
$8 = 0.01
(gdb)

第三个iteration:

(gdb) p dt
$9 = 0.0050000000000000001
(gdb) p Dt
$10 = 0.014999999999999999
(gdb)

可见,dt是不变的,而Dt是随着时间不断变化的.Dt就是总时间.

这是不科学的,用windows科学.

记不得当时为什么选了20和50两种不同数值的window,但得到的average field却是一模一样的,可能是错觉吧.懒得验证了.

编辑于 2018-12-20

文章被以下专栏收录