参数化 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

发表评论