本文摘要(由AI生成):
该文章介绍了在OpenFOAM中如何使用externalFunctionObject文件来定义和执行functionObject,以便在流体动力学仿真中提取和分析数据。文章首先展示了externalFunctionObject文件的内容,包括版本、格式、类别和对象定义等。然后,文章详细描述了如何在控制字典(controlDict)中定义functionObject,并解释了如果忘记定义,如何在计算完成后通过命令执行functionObject。此外,文章还介绍了如何查看和分析提取的数据,包括力系数文件的内容和如何使用gnuplot绘制监控数据图。通过这种方法,用户可以更深入地了解流体动力学仿真的结果,并进行进一步的分析和优化。
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
。
下面以一个使用了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
计算完毕后,算例路径下多出了一个名为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'
图形显示如图所示。