$\lambda_2$ 准则同 $Q$ 准则类似,也是一种漩涡识别方法。

$\lambda_2$ 的定义

将速度梯度 $\nabla \mathbf u$ 分解成对称张量 $\mathbf S$ 和反对称张量 $\mathbf \Omega$ 两部分

\[ \begin{equation} \nabla \mathbf u = \mathbf S + \mathbf \Omega \end{equation} \]

其中

\[ \begin{equation} \mathbf S = \frac{1}{2}\left(\nabla \mathbf u + (\nabla \mathbf u)^T \right) \end{equation} \]

\[ \begin{equation} \mathbf \Omega = \frac{1}{2}\left(\nabla \mathbf u - (\nabla \mathbf u)^T \right) \end{equation} \]

若张量 $\mathbf A$ 定义如下

\[ \begin{equation} \mathbf A = \mathbf S^2 + \mathbf \Omega^2 \end{equation} \]

那么 $\lambda_2$ 即为 $\mathbf A$ 的第二个特征值,记为 $\lambda_2(\mathbf A)$ 。$\lambda_2(\mathbf A) < 0$ 的区域被识别为漩涡区域。

代码实现

注意:OpenFOAM 计算得到的是 $-\lambda_2$,因此在可视化时需要取正值来识别漩涡区域。

OpenFOAM 3.0.x

OpenFOAM 3.0.x 计算 $\lambda_2$ 的代码有两份,分别位于:

  • applications/utilities/postProcessing/velocityField/Lambda2/
  • src/postProcessing/functionObjects/utilities/Lambda2/

utilities 中的代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
        const volTensorField gradU(fvc::grad(U));

        volTensorField SSplusWW
        (
            (symm(gradU) & symm(gradU)) + (skew(gradU) & skew(gradU))
        );

        volScalarField Lambda2
        (
            IOobject
            (
                "Lambda2",
                runTime.timeName(),
                mesh,
                IOobject::NO_READ,
                IOobject::NO_WRITE
            ),
            -eigenValues(SSplusWW)().component(vector::Y)
        );

function objects 中的代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void Foam::Lambda2::execute()
{
    if (active_)
    {
        const fvMesh& mesh = refCast<const fvMesh>(obr_);

        const volVectorField& U =
            mesh.lookupObject<volVectorField>(UName_);

        const volTensorField gradU(fvc::grad(U));

        const volTensorField SSplusWW
        (
            (symm(gradU) & symm(gradU))
          + (skew(gradU) & skew(gradU))
        );

        volScalarField& Lambda2 =
            const_cast<volScalarField&>
            (
                mesh.lookupObject<volScalarField>(type())
            );

        Lambda2 = -eigenValues(SSplusWW)().component(vector::Y);
    }
}

OpenFOAM 4.x 及后续版本

OpenFOAM 4.x 将大部分 utilities 合并到 functionObjects ,并将 functionObjects 框架重写,计算 $\lambda_2$ 的代码位于:

  • src/functionObjects/field/Lambda2/

代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
bool Foam::functionObjects::Lambda2::calc()
{
    if (foundObject<volVectorField>(fieldName_))
    {
        const volVectorField& U = lookupObject<volVectorField>(fieldName_);
        const tmp<volTensorField> tgradU(fvc::grad(U));
        const volTensorField& gradU = tgradU();

        const volTensorField SSplusWW
        (
            (symm(gradU) & symm(gradU))
          + (skew(gradU) & skew(gradU))
        );

        return store
        (
            resultName_,
           -eigenValues(SSplusWW)().component(vector::Y)
        );
    }
    else
    {
        return false;
    }
}