LES直流槽道边界层模拟,如何得到正则化速度u+以及正则化坐标y+?
-
@李东岳 李老师,模拟的平均风和雷诺应力还是准确的,但是$u_\tau$似乎是个很敏感的参数,网格、fvSchemes、fvSolution等设置对$u_\tau$结果都有影响,但平均风和雷诺应力总体区别不大。
最近在模拟《Kim, Y., I.P. Castro and Z. Xie, Divergence-free turbulence inflow conditions for large-eddy simulations with incompressible flow solvers. Computers & Fluids, 2013. 84: p. 56-68.》这篇文章工况,论文中的$u_\tau$沿着计算域的
时间和展向平均结果
如下所示,是非常光滑的:
我模拟的
时间和展向平均结果
为:
就类似 @学流体的小明 的模拟结果,即使用方法三,求整个计算域底面的
时间和空间平均wallShearStress
,也很难与$u_\tau$理论值完全对应上,都有个很小的偏差,因此我的模拟结果不光滑,是很参差。一直在想是否$u_\tau$的计算方法不同导致的。方法三:
通过paraview的filter - integrate variables - 查看 cellData,得到wallShearStress的和以及面积Area,计算固壁面上的wallShearStress平均值,再使用$$ {u_\tau } = \sqrt {\frac{{{\tau _w}}}{\rho }} $$
计算摩擦速度$ {u_\tau }$。注意不可压缩求解器中没有密度,则认为$\rho=1$。
结果是$u_{\tau } = 0.0066952$。 -
前期计算的$\left \langle u_\tau \right \rangle ^+$会出现参差的现象,原来是之前在of8计算复制了一个算例的
wallShearStress
文件,文件中设置executeControl writeTime;
这导致了最终计算的平均只有writeTime
次数,而不是每个timeStep
的结果。参考of2206一个算例的设置就没问题了
of2206中算例设置
wallShearStress { type wallShearStress; libs (fieldFunctionObjects); patches ( bottomWall topWall ); writePrecision 10; writeToFile yes; log yes; executeControl timeStep; executeInterval 1; writeControl writeTime; }
-
空槽道的网格,U+Y+对应结果放下边了。非常感谢李老师和@学流体的小明 的帮助,再就是多看看前边提到的那篇文献,很重要的,认真看完就都没问题了。
网格文件附下,需要自取链接:https://pan.baidu.com/s/1DfaqXnRQMle7JvyHv0WI1A?pwd=kexh
提取码:kexh
-
@2019201300 厉害厉害,LES么?
-
@2019201300 超过上限访问不了了
-
@SSSSK 习惯问题,忘了改默认设置,下边这个应该就没问题了。链接:https://pan.baidu.com/s/16PwL1nIOXCucqKU3XoZ1_A?pwd=gg61
提取码:gg61 -
@2019201300 感谢感谢
-
看到 cfd online 的后处理代码:compressibleyPlusLES,感觉修改下作为后处理工具,不失为一个更简单直接的方法。
volScalarField yPlusTemp ( IOobject ( "yPlusTemp", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionedScalar("yPlusTemp", dimless, 0.0) ); volVectorField uPlus ( IOobject ( "uPlus", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionedVector("uPlus", dimless, vector::zero) ); volScalarField uTau ( IOobject ( "uTau", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionedScalar("uTau", dimVelocity, 0.0) ); volScalarField yPlus ( IOobject ( "yPlus", runTime.timeName(), mesh, IOobject::NO_READ, IOobject::NO_WRITE ), mesh, dimensionedScalar("yPlus", dimless, 0.0) ); Info<< "Reading field UMean\n" << endl; volVectorField UMean ( IOobject ( "UMean", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ), mesh ); Info<< "Reading field U\n" << endl; volVectorField U ( IOobject ( "U", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ), mesh ); Info<< "Reading field rho\n" << endl; volScalarField rho ( IOobject ( "rho", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::NO_WRITE ), mesh ); # include "compressibleCreatePhi.H" Info<< "successs1\n" << endl; autoPtr<basicThermo> pThermo ( basicThermo::New(mesh) ); basicThermo& thermo = pThermo(); Info<< "successs2\n" << endl; autoPtr<compressible::LESModel> sgsModel ( compressible::LESModel::New(rho, UMean, phi, thermo) );
/*---------------------------------------------------------------------------*\ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation \\/ M anipulation | ------------------------------------------------------------------------------- License This file is part of OpenFOAM. OpenFOAM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenFOAM is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Application yPlusLES Description Calculates and reports yPlus and uPlus for all wall patches, for the specified times, for compressible LES. \*---------------------------------------------------------------------------*/ #include "fvCFD.H" //#include "incompressible/singlePhaseTransportModel/singlePhaseTransportModel.H" //aali #include "compressible/LES/LESModel/LESModel.H" #include "basicThermo.H" //ali #include "wallFvPatch.H" #include "LESModel.H" #include "nearWallDist.H" #include "wallDist.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // int main(int argc, char *argv[]) { timeSelector::addOptions(); #include "setRootCase.H" # include "createTime.H" instantList timeDirs = timeSelector::select0(runTime, args); # include "createMesh.H" forAll(timeDirs, timeI) { runTime.setTime(timeDirs[timeI], timeI); Info<< "Time = " << runTime.timeName() << endl; fvMesh::readUpdateState state = mesh.readUpdate(); // Wall distance wallDist y(mesh, true); if (timeI == 0 || state != fvMesh::UNCHANGED) { Info<< "Calculating wall distance\n" << endl; Info<< "Writing wall distance to field " << y.name() << nl << endl; y.write(); } #include "createFields.H" volScalarField::GeometricBoundaryField d = nearWallDist(mesh).y(); volScalarField muEff(sgsModel->muEff()); const fvPatchList& patches = mesh.boundary(); dimensionedScalar uTauAvg("uTauAvg", dimVelocity, 0); const volScalarField muLam(sgsModel->mu()); scalar nPatch = 0; Info<< "Summary: " << nl << endl; forAll(patches, patchi) { const fvPatch& currPatch = patches[patchi]; if (typeid(currPatch) == typeid(wallFvPatch))//isA<wallFvPatch>(currPatch)) { yPlusTemp.boundaryField()[patchi] = d[patchi] *sqrt ( muEff.boundaryField()[patchi]/rho.boundaryField()[patchi] *mag(UMean.boundaryField()[patchi].snGrad()) ) /muLam.boundaryField()[patchi]/rho.boundaryField()[patchi]; const scalarField& YpTemp = yPlusTemp.boundaryField()[patchi]; //effective viscosity used in the calculation of u* uTau.boundaryField()[patchi] = sqrt ( sgsModel->muEff() *mag(UMean.boundaryField()[patchi].snGrad()) /sgsModel->rho() ); const fvPatchScalarField& uTauWall = uTau.boundaryField()[patchi]; dimensionedScalar uTauTmp("uTauTmp", dimVelocity, average(uTauWall)); uTauAvg += uTauTmp; nPatch ++; Info<< "Patch " << patchi << " named " << currPatch.name() << " y+ : min: " << min(YpTemp) << " max: " << max(YpTemp) << " average: " << average(YpTemp) << " avgUGradWall: " << average(mag(U.boundaryField()[patchi].snGrad())) << nl << endl; } } uTauAvg /= nPatch; Info << " avg. friction velocity uTau is: " << uTauAvg.value() << " (averaged over " << nPatch << " wall(s))" << nl <<endl; //yPlus is = u* x y/nu yPlus = y.y() * uTauAvg / ((sgsModel->mu()) / (sgsModel->rho())); uPlus = UMean / uTauAvg; Info << "Writing yPlus and uPlus to corresponding fields." << nl <<endl; yPlus.write(); uPlus.write(); // Info<< "Writing yPlus to field " // << yPlus.name() << nl << endl; // // yPlus.write(); } Info<< "End\n" << endl; return 0; } // ************************************************************************* //