アダプティブメッシュ

2011年8月27日

はじめに

アダプティブメッシュを使ってみる。アダプティブメッシュを使うには、 dynamicMesh が使えるようになっている必要がある。はじめに interDyMFoam で試し、その後 simpleFoam で dynamicMesh を使えるようにしてアダプティブメッシュを試してみる。

使用バージョン

OpenFOAM 2.0.1

ファイル

interDyMFoam

interDyMFoam を使えば、アダプティブメッシュが使える。interFoam のケースで計算してみよう。

$ cp -r $FOAM_TUTORIALS/multiphase/interFoam/laminar/damBreak/ .
$ cp -r $FOAM_TUTORIALS/multiphase/interDyMFoam/ras/damBreakWithObstacle/constant /dynamicMeshDict damBreak/constant/

境界タイプが empty だと計算できないので、ケースフォルダの constant/polyMesh/boundary の defaultFaces の type と、0/U, alpha1, p の defaultFaces の type を symmetryPlane にする。

計算に時間がかかるので、constant/dynamicMeshDict の maxRefinement を 1 にする。

$ cd damBreak
$ blockMesh
$ setFields
$ interDyMFoam

液相の界面のメッシュが細分化されているのがわかる。

simpleFoam でアダプティブメッシュ

simpleFoam の dynamicMesh 対応

simpleFoam でアダプティブメッシュを使うにはどうしたらよいのだろう。アダプティブメッシュは dynamicMesh の一種なので、simpleFoam を dynamicMesh に対応させる必要がある。そこで、 dynamicMesh 対応版 simpleFoam である "simpleDyMFoam" を作る。

$ cp -r $FOAM_APP/solvers/incompressible/simpleFoam/ simpleDyMFoam
$ cd simpleDyMFoam
$ mv simpleFoam.C simpleDyMFoam.C

Make/file を修正。

simpleDyMFoam.C

EXE = simpleDyMFoam

プログラムはソースディレクトリ内にできる。

Make/options に dynamicMesh 用の設定を追加。

EXE_INC = \
    ...
    -I$(LIB_SRC)/dynamicMesh/lnInclude \
    -I$(LIB_SRC)/meshTools/lnInclude \
    -I$(LIB_SRC)/dynamicFvMesh/lnInclude

EXE_LIBS = \
    ...
    -ldynamicMesh \
    -lmeshTools \
    -ldynamicFvMesh

simpleDyMFoam.C を修正。

#include "fvCFD.H"
#include "singlePhaseTransportModel.H"
#include "RASModel.H"
#include "simpleControl.H"
#include "dynamicFvMesh.H"

...

int main(int argc, char *argv[])
{
    #include "setRootCase.H"
    #include "createTime.H"
    //#include "createMesh.H"
    #include "createDynamicFvMesh.H"
    #include "createFields.H"
    #include "initContinuityErrs.H"

    ...

    while (simple.loop())
    {
        Info<< "Time = " << runTime.timeName() << nl << endl;

        p.storePrevIter();

        mesh.update();
	...

コンパイル。

$ wmake

動作確認

プログラムができたら、キャビティのケースで試してみよう。

$ cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity

設定ファイルを simpleFoam のケースからコピー。

$ cp $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily/system/fvSolution cavity/system
$ cp $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily/system/fvSchemes cavity/system
$ cp $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily/constant/RASProperties cavity/constant/
$ cp $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily/0/k cavity/0
$ cp $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily/0/epsilon cavity/0
$ cp $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily/0/R cavity/0
$ cp $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily/0/nuTilda cavity/0
$ cp $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily/0/nut cavity/0

system/fvSolution の SIMPLE に以下を追加。

    pRefCell        0;
    pRefValue       0;

system/constant/transportProperties に以下を追加。

transportModel  Newtonian;

フィールドデータ p, k, epsilon, R, nuTilda, nut を修正する。frontAndBack の type は symmetryPlane にする。また、constant/polyMesh/boundary の frontAndBack の type も symmetryPlane にする。

とりあえず simpleFoam で計算できるかどうかテスト。

$ cd cavity
$ simpleFoam

simpleFoam で計算できることが確認できたら、dynamicMesh の設定ファイル dynamicMeshDict を用意。

$ cp $FOAM_TUTORIALS/multiphase/interDyMFoam/ras/damBreakWithObstacle/constant/dynamicMeshDict constant/

constant/dynamicMeshDict を修正。

dynamicRefineFvMeshCoeffs
{
    refineInterval  1;
    field           p;

field は volScalarField でないといけない。ここではとりあえずの動作確認のために p を指定する。

実行。

$ ../simpleDyMFoam/simpleDyMFoam

速度勾配に応じた細分化

アダプティブメッシュ用のスカラーフィールドデータを用意しよう。ここでは速度勾配を使用する。simpleDyMFoam を以下のように修正する。

createFields.H

    Info << "Reading field U\n" << endl;
    volVectorField U
    (
        IOobject
        (
            "U",
            runTime.timeName(),
            mesh,
            IOobject::MUST_READ,
            IOobject::AUTO_WRITE
        ),
        mesh
    );

    volScalarField gradU
    (
        IOobject
        (
            "gradU",
            runTime.timeName(),
            mesh,
            IOobject::NO_READ,
            IOobject::AUTO_WRITE
        ),
        mesh,
	dimensionSet(0, 0, 0, 0, 0, 0, 0)
    );

simpleDyMFoam.C

#include <cfloat>

        ...
        turbulence->correct();

        volScalarField gradU0 = mag(fvc::grad(U));
        gradU = gradU0/max(gradU0);

        runTime.write();
        ...

アダプティブメッシュの設定が容易になるように、速度勾配を 0 〜 1 にスケーリングしている。

constant/dynamicMeshDict を以下のようにする。

dynamicRefineFvMeshCoeffs
{
    refineInterval  10;
    field           gradU;
    lowerRefineLevel 0.1;
    upperRefineLevel 1.;
    unrefineLevel   0;
    nBufferLayers   1;
    maxRefinement   3;
    ...

はじめは

    lowerRefineLevel 0.;
    upperRefineLevel 0.;
である程度計算させたあと、
    lowerRefineLevel 0.1;
    upperRefineLevel 1.;
にして計算を継続する。

system/controlDict

application     simpleDyMFoam;

startFrom       startTime;

startTime       0;

stopAt          endTime;

endTime         50;

deltaT          1;

writeControl    timeStep;

writeInterval   10;

50 step ずつ 2 回にわけて計算する。

計算結果