$\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;
}
}
|