Code of the Week #16: RASModel kOmegaSST

kOmegaSST 在 foam-extend-4.0 中的模型为

\rho\frac{\partial{ k}}{\partial t} + \rho\boldsymbol{u}\cdot \nabla k = \nabla\cdot \left( \rho D_k \nabla k \right) - \frac{2}{3} \rho k \left( \nabla \cdot\boldsymbol{u} \right) + \rho\min\left( G,\, c_1\beta^{*} \omega k\right) + S_k

式中, D_k=\alpha_k \times \nu_t + \nuG=\nu_t \mathbf{S}^2

\rho \frac{\partial{\omega}}{\partial t} + \rho\boldsymbol{u}\cdot \nabla (\omega ) = \nabla\cdot \left( \rho D_\omega \nabla \omega \right) + \frac{\rho \gamma \min\left( G,\, c_1\beta^{*} \omega k\right)}{\nu_t} - \frac{2}{3} \rho \gamma \omega \left( \nabla\cdot \boldsymbol{u} \right) - \rho \beta \omega^2 - \rho \left(F_1 - 1\right) C\! D_{k\omega} + S_\omega

式中,

D_\omega=\alpha_\omega \times \nu_t + \nu\\ F_1 = \tanh(arg_1^4)\\ arg_1 = \min\left\{ \min\left[\max\left(\frac{\sqrt{k}}{\beta^* \omega d},\,\frac{500\nu}{d^2\omega} \right), \,\frac{4\rho\sigma_{\omega2} k}{C\! D_{k\omega}^+ d^2} \right], 10\right\}\\ C\! D_{k\omega}^+ = \max\left(C\! D_{k\omega} ,\, 10^{-10}\right)\\ C\! D_{k\omega} = 2\rho\sigma_{\omega2}\dfrac{1}{\omega}\frac{\partial k}{\partial x_j} \frac{\partial \omega}{\partial x_j}\\ \nu_t = a_1 \frac{k}{\max (a_1 \omega_, b_1 F_{23} \mathbf{S})}\\ F_{2} = \tanh(arg_2^2)\\ arg_2 = \min\left[ \max\left(\frac{2\sqrt{k}}{\beta^* \omega d} ,\, \dfrac{500\nu}{d^2\omega}\right),\, 100\right]\\ F_3 = 1-\tanh(arg_3^4)\\ arg_3 = \min\left(\frac{150\nu}{\omega d^2}, \, 10 \right)\\ F_{23} = F_2 F_3,\, \text{if}\, F_3\neq 0

式中, d 是网格中心点到最近的 wall 的距离, \mathbf{S}=\sqrt{2\left|\dfrac{1}{2}\left(\nabla\boldsymbol{u} + (\nabla\boldsymbol{u})^T \right)\right|^2}
对于系数 \alpha_k\alpha_\omega\gamma

\alpha_k =\alpha_{k1} F_1 + \alpha_{k2}(1-F_1) ,\\ \alpha_\omega =\alpha_{\omega1} F_1 + \alpha_{\omega2}(1-F_1), \\ \gamma=\gamma_1 F_1 + \gamma_2 (1-F_1).
α_{k1} α_{k2} α_{ω1} α_{ω2} β_1 β_2 γ_1 γ_2 \beta^∗ a_1 b_1 c_1
0.85 1.0 0.5 0.856 0.075 0.0828 5/9 0.44 0.09 0.31 1.0 10.0

k 的估计

k=\frac{3}{2}\left(I u_{ref} \right)^2

其中 I 为湍流强度, u_{ref} 为参考速度。

\omega 的估计

\omega = \frac{k^{0.5}}{C_{\mu} L}

式中, C_μ=0.09L 为参考长度.

在 foam-extend-4.0 版本的 kOmegaSST 中关键的代码如下:

void kOmegaSST::correct()
{
    // Bound in case of topological change
    // HJ, 22/Aug/2007
    if (mesh_.changing())
    {
        bound(k_, k0_);
        bound(omega_, omega0_);
    }

    RASModel::correct();

    if (!turbulence_)
    {
        return;
    }

    if (mesh_.changing())
    {
        y_.correct();
    }

    const volScalarField S2(2*magSqr(symm(fvc::grad(U_))));
    volScalarField G("RASModel::G", nut_*S2);

    // Update omega and G at the wall
    omega_.boundaryField().updateCoeffs();

    const volScalarField CDkOmega
    (
        (2*alphaOmega2_)*(fvc::grad(k_) & fvc::grad(omega_))/omega_
    );

    const volScalarField F1(this->F1(CDkOmega));

    // Turbulent frequency equation
    fvScalarMatrix omegaEqn
    (
        fvm::ddt(omega_)
      + fvm::div(phi_, omega_)
      + fvm::SuSp(-fvc::div(phi_), omega_)
      - fvm::laplacian(DomegaEff(F1), omega_)
     ==
        gamma(F1)
       *min
        (
            S2,
            (c1_/a1_)*betaStar_*omega_*max(a1_*omega_, b1_*F23()*sqrt(S2))
        )
      - fvm::Sp(beta(F1)*omega_, omega_)
      - fvm::SuSp
        (
            (F1 - scalar(1))*CDkOmega/omega_,
            omega_
        )
    );

    omegaEqn.relax();

    // No longer needed: matrix completes at the point of solution
    // HJ, 17/Apr/2012
//     omegaEqn.completeAssembly();

    solve(omegaEqn);
    bound(omega_, omega0_);

    // Turbulent kinetic energy equation
    fvScalarMatrix kEqn
    (
        fvm::ddt(k_)
      + fvm::div(phi_, k_)
      + fvm::SuSp(-fvc::div(phi_), k_)
      - fvm::laplacian(DkEff(F1), k_)
     ==
        min(G, c1_*betaStar_*k_*omega_)
      - fvm::Sp(betaStar_*omega_, k_)
    );

    kEqn.relax();
    solve(kEqn);
    bound(k_, k0_);                 // 限制器

    // Re-calculate viscosity
    // Fixed sqrt(2) error.  HJ, 10/Jun/2015
    nut_ = a1_*k_/max(a1_*omega_, b1_*F23()*sqrt(S2));
    nut_ = min(nut_, nuRatio()*nu());    // 限制湍流粘度,缺省最大值 nuRatio = 1E+06
    nut_.correctBoundaryConditions();
}

bound() 是 OpenFOAM 里面的限制器,文件是 src/finiteVolume/cfdTools/general/bound/bound.C,其部分代码如下:

void Foam::bound(volScalarField& vsf, const dimensionedScalar& vsf0)
{
    scalar minVsf = min(vsf).value();

    if (minVsf < vsf0.value())
    {
        Info<< "bounding " << vsf.name()
            << ", min: " << minVsf
            << " max: " << max(vsf).value()
            << " average: " << gAverage(vsf.internalField())
            << endl;

        vsf.internalField() = max
        (
            max
            (
                vsf.internalField(),
                fvc::average(max(vsf, vsf0))().internalField()
                // Bug fix: was assuming bound on zero.  HJ, 25/Nov/2008
                *pos(vsf0.value() - vsf.internalField())
            ),
            vsf0.value()
        );

        vsf.correctBoundaryConditions();
        vsf.boundaryField() = max(vsf.boundaryField(), vsf0.value());
    }
}

参考文献

  1. F. R. Menter, M. Kuntz, R. Langtry. Ten Years of Industrial Experience with the SST Turbulence Model, in in Turbulence, Heat and Mass Transfer 4, 2003, pp. 625-632
  2. https://turbmodels.larc.nasa.gov/sst.html