参数化 blockMeshDict

blockMesh 是 OpenFOAM 最基础的网格划分工具,适合处理简单的体型。但是 blockMeshDict 文件往往被点坐标占据大量篇幅,这些数字毫无逻辑。如果点坐标很多的话,很难将坐标值和点序号对应起来,这样后面 blocks、edges 和 faces 的定义根本看不明白。相信很多初学者都像我一样有类似的体验。

  这个文件读起来困难,写起来就更困难了。需要输入大量坐标值不说,定义 blocks 的时候还容易看错点序号。如果要修改体型,一个数字一个数字改起来更是痛苦。

  笔者曾考虑用脚本语言生成 blockMeshDict,又觉得这种实现方法不够优雅,所以先试着搜索了一下,发现了一个优雅的做法,Writing a blockMeshDict file with variables。我总结一下。

  先看一个参数化的例子,这个 blockMeshDict 文件定义了一个横截面为扇形的柱体。

gedit $FOAM_TUTORIALS/incompressible/simpleFoam/pipeCyclic/system/blockMeshDict 
Code language: PHP (php)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

convertToMeters 1;

//- Half angle of wedge in degrees
halfAngle 45.0;

//- Radius of pipe [m]
radius 0.5;

radHalfAngle    #calc "degToRad($halfAngle)";
y               #calc "$radius*sin($radHalfAngle)";
minY            #calc "-1.0*$y";
z               #calc "$radius*cos($radHalfAngle)";
minZ            #calc "-1.0*$z";

vertices
(
    (0.0    0.0 0)      //0
    (10     0.0 0)
    (10     0.0 0)      //2
    (0.0    0.0 0)

    (0.0    $minY $z)   //4
    (10     $minY $z)
    (10     $y $z)      //6
    (0.0    $y $z)

);Code language: PHP (php)

  可以看到定义点坐标时,使用了 minY、y、z 等变量,这些变量是用半径 radius 和半顶角 radHalfAngle 计算出来的。这个例子中,柱体的长度是10,这个数字没有用参数替代,如果把坐标里的数字都用变量名替代,代码的可读性还可以进一步提高。

  上例中用到的 #calc 指令支持 C++ 标准函数。如果计算很复杂,还可以使用 #codeStream 指令,详见OpenFOAM User Guide: 4.2 Basic input/output file format

  最后请教读者们一个问题,类似 #calc 这种用法是 C++ 的什么特性,和 #include 一样是预处理指令吗?如果想了解更多相关内容,应该用什么关键词搜索呢?

常恭

作者: 常恭

略懂 OpenFOAM

发表评论