首页/文章/ 详情

OpenFOAM|11 了解functionObject

精品
作者优秀平台推荐
详细信息
文章亮点
作者优秀
优秀教师/意见领袖/博士学历/特邀专家
平台推荐
内容稀缺
5月前浏览6912

本文摘要(由AI生成):

该文章介绍了在OpenFOAM中如何使用externalFunctionObject文件来定义和执行functionObject,以便在流体动力学仿真中提取和分析数据。文章首先展示了externalFunctionObject文件的内容,包括版本、格式、类别和对象定义等。然后,文章详细描述了如何在控制字典(controlDict)中定义functionObject,并解释了如果忘记定义,如何在计算完成后通过命令执行functionObject。此外,文章还介绍了如何查看和分析提取的数据,包括力系数文件的内容和如何使用gnuplot绘制监控数据图。通过这种方法,用户可以更深入地了解流体动力学仿真的结果,并进行进一步的分析和优化。


1 介绍

OpenFOAM求解计算过程中,可以使用functionObject执行数据的提取与处理。functionObject是按指定间隔执行的小段代码,无需显式链接到应用程序,当在使用的过程中,可以将特定的数据写入到文件中以方便图形绘制及后处理。

functionObject在controlDict字典文件中进行指定,且在预定义的时间点上执行操作。

functionObject在OpenFOAM求解计算的过程中可以实时修改。在OpenFOAM计算完毕后也可以执行functionObject,例如,可以使用functionObjects计算马赫数,涡量场,并在给定点或沿直线的速度进行采用。

在文件夹$FOAM_SRC/functionObjects中可以找到functionObject的源代码。该文件夹中包含一些子文件夹(field、forces、lagrangian、solver、utilities等),分别对应着不同的使用类型,在子文件夹下存放各种不同类型的functionObject,如courantNo、forceCoeffs等。如下图所示。

除了functionObjects外,在路径$FOAM_SRC\sampling中可以找到采用工具的所有源代码。

functionObject在字典文件controlDict中定义。如下面定义了一个fieldMinMax的对象,该对象用于在指定时间点上输出计算区域中的压力、速度等物理量的最大最小值:

// 对象名称,由用户给定
minmaxdomain
{
   // 对象类型,与上图中相对应的子文件夹名称一致
   type fieldMinMax;
   // 使用库
   functionObjectLibs ("libfieldFunctionObjects.so");
   // 打开或关闭functionObject
   enabled true;
   // 指定输出的物理量形式,这是子字典
   mode component;
   // 指定数据保存频率
   writeControl timeStep;
   writeInterval 1;
   // 指定是否在屏幕上显示输出信息
   log true;
   // 指定输出的物理场,这是子字典
   fields (p U nuTilda nut k omega);
}

OpenFOAM中包含了许多functionObject,一些特定的functionObject使用起来较为复杂。另外,functionObjects可以具有许多选项和一些限制,最好的建议是阅读doxygen文档或源代码,以学习如何使用functionObjects。

注:functionObjects源代码路径:$WM_PROJECT_DIR/src/postProcessing/functionObjects;sampling工具源代码路径:$WM_PROJECT_DIR/src/sampling;functionObject所需的数据库源代码路径$FOAM_SRC/OpenFOAM/db/functionObjects

2 算例

下面以一个使用了functionObject的算例来进行描述。该算例计算的是一个三段翼外流场,如下图所示。

通过使用functionObject在计算过程中输出物理量(如yplus、涡量、物理场的平均值、力、力系数、物理场的最大最下周、进出口流量等)。

functionObject在controlDict字典文件中定义,打开controlDict文件:

FoamFile
{
   version     2.0;
   format      ascii;
   class       dictionary;
   object      controlDict;
}
// * * * * * * * * * * * * * * * * //

application     simpleFoam;
startFrom       startTime;
startTime       0;
stopAt          endTime;
endTime         2000;
deltaT          1;
writeControl    runTime;
writeInterval   50;
purgeWrite      100;
writeFormat     binary;  
writePrecision  8;
writeCompression off;
timeFormat      general;
timePrecision   6;
runTimeModifiable yes;

//下面为functionObject的定义
functions
{
// 定义第一个functionObject,命名为forces_object
// 输出的数据将保存在文件夹postProcessing/forces_object中
// 注意不同的functionObjects需要定义的条目是不同的
forces_object
{
   // 指定类型为forces,必须项
   type forces;
   // 加载functionObject库
   functionObjectLibs ("libforces.so");

   // 指定数据输出频率
   writeControl   timeStep;
   writetInterval  1;

   // 激活functionObject对象
   enabled true;

   // 指定参与计算的边界,必须项
   patches ("wall_slat" "wall_airfoil" "wall_flap");

   //// 指定压力场与速度场的变量名称
   pName p;
   Uname U;

   // 参考密度值。它仅需要针对不可压缩的流进行定义。
   // 对于可压缩流,将使用计算的密度代替
   rho rhoInf;
   rhoInf 1.0;

   //// 指定力矩计算所需的旋转中心
   CofR (0 0 0);
}
// 关于forces的写法,可参阅文档:
/* https://cpp.openfoam.org/v8/classFoam_1_1functionObjects_1_1forces.html*/
////////////////////////////////////////////
forceCoeffs_object
{
   // 指定类型为力系数,该项为必选项
   type forceCoeffs;

   functionObjectLibs ("libforces.so");
   // 激活此对象
   enabled true;
   // 指定参与计算的边界名称,此项为必选项
   patches ("wall_slat" "wall_airfoil" "wall_flap");
   // 指定变量名称
   pName p;
   Uname U;

   // 仅用于不可压缩流动
   rho rhoInf;
   rhoInf 1.0;

   // 将数据写入到文件中
   log true;
   // 指定旋转中心坐标
   CofR (0.0 0 0);
   // 用于计算系数的参考值,4个均为必选项
   pitchAxis (0 0 1);    // 俯仰轴
   magUInf 1.0;    // 参考速度
   lRef 1;        // 用于力矩计算的参考长度
   Aref 1;        // 用于系数计算的参考面积

   // 指定数据的写入频率
   writeControl   timeStep;
   writeInterval  1;

   // 指定升力方向与阻力方向,必选项
   // 对于升力来讲,其值为攻角的三角函数(-sin,cos,0)
   // 对于阻力,其值为攻角的三角函数(cos,sin,0)
   // 注意角度换算为弧度
   liftDir     (0 1 0);      
   dragDir     (1 0 0);          
}  
//////////////////////////////////

minmaxdomain
{
   // 指定类型为fieldMinMax,必选项
   // 用于输出计算域内指定物理量的最大最小值
   type fieldMinMax;

   functionObjectLibs ("libfieldFunctionObjects.so");

   enabled true;
   // 指定计算物理场的分量,这里还可以指定magnitude
   mode component;
   // 指定数据写入频率
   writeControl timeStep;
   writeInterval 1;

   log true;
   // 指定需要输出的物理场
   fields (p U nuTilda nut k omega);
}

///////////////////////////////////////////
yplus
{
   // 指定类型为yplus,用于输出y 值
   type yPlus;
   functionObjectLibs ("libutilityFunctionObjects.so");
   enabled true;
   log    true;
   writeControl outputTime;  
}
///////////////////////////////////////

fieldAverage1
{
   // 指定类型fieldAverage,输出物理场的平均值
   type            fieldAverage;
   libs ( "libfieldFunctionObjects.so" );
   writeControl    writeTime;

   enabled         true;
   log             true;
   timeStart       100;
   // 下面指定需要输出的物理场,包括U,p及nut
   fields
   (
       U
       {
                mean        on;
                prime2Mean  on;
                base        time;
       }

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

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

// 直接包含外部定义的functionObject
#include "externalFunctionObject"
};

这里使用了externalFunctionObject文件,该文件内容如下所示。

{
   version     2.0;
   format      ascii;
   class       dictionary;
   object      functionObject;
}


//functions
//{
// 定义了监测点数据提取
probes_online
{
   type probes;
   functionObjectLibs ("libfieldFunctionObjects.so");
   enabled true;
   writeControl timeStep;
   writeInterval 1;

   probeLocations
   (
       (1 0 0)
       (2 0 0)
       (2 0.25 0)
       (2 -0.25 0)
   );

   fields
   (  
       U
       p
    );

}

// 定义了涡量提取
vorticity
{
   type vorticity;
   functionObjectLibs ("libfieldFunctionObjects.so");
   enabled true;
   log    true;
   writeControl outputTime;  
}

//}

这里的functionObject可以在运行时随求解器一起执行。

但有时可能事先忘记了在controlDict字典中定义functionObject,导致计算完毕后数据并未提取出来。OpenFOAM允许用户在求解计算完毕后执行functionObject,此时可以在controlDict文件中添加functionObject,然后利用命令:

name_of_the_solver -postProcess –dict dictionary_location

也可以将functionObject写入到一个独立的文件中,然后执行上面的操作命令。一个简单的调用例子:

simpleFoam -postProcess -dict system/externalFunctionObject –noZero
simpleFoam -postProcess -dict system/externalFunctionObject –time 500:2000

3 查看结果

计算完毕后,算例路径下多出了一个名为postProcessing的文件夹。

该文件夹中的文件组织形式如下所示。

此时可以gnuplot绘制监控得到的数据图。

如查看力系数文件(路径postProcessing/forceCoeffs_object/0/forceCoeffs.dat),其内容如下图所示。

可以使用gnuplot查看阻力系数变化曲线:

set xlabel 'iter'
set ylabel 'cd'
plot [10:][] 'postProcessing/forceCoeffs_object/0/forceCoeffs.dat' u 1:3 w l title 'cd' lw 2

得到的阻力系数随迭代过程的变化曲线如下图所示:

类似方式可以查看升力系数:

set xlabel 'iter'
set ylabel 'cl'
plot [10:][] 'postProcessing/forceCoeffs_object/0/forceCoeffs.dat' u 1:4 w l title 'cl'

图形显示如图所示。


OpenFOAM代码&命令
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2020-11-03
最近编辑:5月前
CFD之道
博士 | 教师 探讨CFD职场生活,闲谈CFD里外
获赞 2566粉丝 11299文章 734课程 27
点赞
收藏
作者推荐
未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习 福利任务 兑换礼品
下载APP
联系我们
帮助与反馈