Code of the Week #10: boundaryField p U

今天要介绍的是边界条件的设置,以 cavity 算例为例。这是一个计算流体力学里面的经典算例,称为“顶盖驱动流”,即在一个密闭空腔内,由于某一边界(顶盖)的运动导致的空腔内流体的运动。

在 pisoFoam 的算例 cavity (tutorials/incompressible/pisoFoam/ras/cavity) 里的 0/U 文件是这样的:

FoamFile
{
    version     2.0;
    format      ascii;          // 格式: ascii 为字符格式,binary 为二进制格式
    class       volVectorField; // 变量所属的类
    object      U;              // 变量名 (对象)
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions      [0 1 -1 0 0 0 0]; // 单位,从左到右分别为 SI [kg m s K mol A cd]

internalField   uniform (0 0 0);  // 内部场, uniform 表示统一场;nonuniform 为非统一场,以 list 显示

boundaryField    // 边界定义
{
    movingWall   // 边界名称
    {
        type            fixedValue;       // 边界类型
        value           uniform (1 0 0);  // 边界值,设置方式同 internalField,
    }                                     // 此处 1 0 0 分别对应 x y z 方向的速度,单位由 dimensions 指定

    fixedWalls
    {
        type            fixedValue;
        value           uniform (0 0 0);
    }

    frontAndBack
    {
        type            empty;  // 不求解
    }
}

cavity 的网格如下,其边界如下左图,上边界是 movingWall,左、右、下边界为 fixedWalls,前后为 frontAndBack (未显示)。

边界的类型,从数学上讲,基本的有两种,一种是指定数值,一种是指定梯度。对于 cavity 这一经典算例,U 的边界有

U_{\text{movingWall}} = (1,\,0,\,0) \\ U_{\text{fixedWalls}} = (0,\,0,\,0)

指的是 movingWall 的移动速度为 1 m/s,方向是 x 方向,而 fixedWalls 的速度为 0 。

对应的 p 的边界指定就是

dimensions      [0 2 -2 0 0 0 0];

internalField   uniform 0;

boundaryField
{
    movingWall
    {
        type            zeroGradient; // 梯度指定,零梯度,无须设定 value 
    }

    fixedWalls
    {
        type            zeroGradient;
    }

    frontAndBack
    {
        type            empty;
    }
}

对于通常计算 U, p 的解析,其指定的方式主要有

变量 边界 1 边界 2
U fixedValue zeroGradient
p zeroGradient fixedValue

变量 边界 1 边界 2
U zeroGradient zeroGradient
p fixedValue fixedValue

如果有多个边界,注意的是 U 不能全部都是 fixedValue,这样很容易出现计算错误。

OpenFOAM 中基本的边界条件有,

类型 解释 需要的变量 (值)
calculated 指边界上的值由场的计算(或赋值)得来
fixedValue 指定边界为固定值, 这也是其他一些边界条件的基类 value
fixedGradient 指定边界上的梯度为固定值 gradient
zeroGradient 指定边界上的梯度为 0,指边界上的值为内部网格的值
mixed 提供了一个基本的混合的边界,即:固定值和固定梯度同时满足,由 valueFraction 指定 fixedValue 和 fixedGradient 的方式,如 valueFraction = 1, 则由 refValue 指定固定值,若 valueFraction = 0,则由 refGradient 指定 valueFraction refValue refGradient
directionMixed 具有方向性的 mixed 边界 refValue refGradient valueFraction value
extrapolatedCalculated 此边界计算时指定零梯度,但也可以被赋值。snGrad 返回边界的梯度值(由边界所属的网格与边界的值计算得来,而不是返回 0)

其他边界条件可参考:Standard boundary conditions

我对这个设定empty面有疑惑。按照上面的设定应该是FrontandBack 被设定为了空。这个FrontandBack 不是正对屏幕(即面本身平行屏幕画了网格那个面)和在屏幕背后的两个面吗?设定为空后应该不参与运算,为什么要给它们画网格呢?

边界设定为 empty 后,这两个面的法向方向上的量不求解,这个方向上的网格只有一层,是穿过屏幕的,所看到的网格实际上是另外两个方向上的格子。

需要注意的是,对于 empty 边界:

  • 介于 empty 边界之间的网格只能有一层;
  • 在这一方向上,也就是层高,必须是一致的;
  • 从这个边界的法向上看,所有的点都在同一位置,即除了这一方向上的值不同外,其余两个方向的量是相同的。

OpenFOAM.org 推荐的边界
https://cpp.openfoam.org/v4/pageBoundaryConditions.html