境界条件の作成

2014年9月20日

はじめに

境界条件の作成について。

使用バージョン

OpenFOAM 2.3.0

ステップ

ここでは、次のステップで境界条件の作成方法の習得を進める。

  1. 実行時コードコンパイルによる実装
  2. 実行時コードコンパイルにより作成されたコードを利用した実装
  3. 既存のコードをベースにした実装

実行時コードコンパイルによる実装

たとえば、pimpleFoam のチュートリアルケース pitzDaily を使って、非定常流入条件を指定する。

    inlet
    {
        //type            fixedValue;
        //value           uniform (10 0 0);
        type            codedFixedValue;
        value           uniform (0 0 0);
        redirectType    sineVelocity;
        code
        #{
            fvPatchField<vector> f
            (
                patch().lookupPatchField<volVectorField, vector>("U")
            );

            const scalar t = db().time().timeOutputValue();
            const scalar pi = constant::mathematical::pi;

            forAll(patch().Cf(), i)
            {
                f[i] = vector(10.*sin(2.*pi*t/0.1), 0, 0);
            }

            operator==(f);
        #};
    }

u = 10*sin(2*pi*t/0.1) としている。周期は 0.1 s。

pimpleFoam を実行すると、dynamicCode というディレクトリができ、その中に自動作成された境界条件のコードが格納される。

実行時コードコンパイルにより作成されたコードの利用

dynamicCode の中のコードを利用して境界条件を作成する。

$ cd dynamicCode/sineVelocity

Make/files を編集。

/* dynamicCode:
 * SHA1 = 5fbd59f531f5427d360db88650500b0534d5f992
 */
fixedValueFvPatchFieldTemplate.C

/*LIB = $(PWD)/../platforms/$(WM_OPTIONS)/lib/libsineVelocity_5fbd59f531f5427d360db88650500b0534d5f992*/
LIB = $(FOAM_USER_LIBBIN)/libsineVelocity

コンパイル。

$ wclean
$ wmake

$(FOAM_USER_LIBBIN)/libsineVelocity.so ができる。作成した境界条件を利用するには、controlDict にライブラリの読み込みを指定する。

system/controlDict

libs
(
  "libsineVelocity.so"
);

0/U

    inlet
    {
        type            sineVelocity;
        value           uniform (0 0 0);
    }

パラメタの追加

せっかくなので、u = A*sin(2*pi*t/0.1) などとして A を指定できるようにしたい。

dynamicCode の fixedValueFvPatchFieldTemplate.H を編集して、パラメタ A を追加。

class sineVelocityFixedValueFvPatchVectorField
:
    public fixedValueFvPatchField<vector>
{
    const scalar A_;
    
    ...

fixedValueFvPatchFieldTemplate.C

sineVelocityFixedValueFvPatchVectorField::
sineVelocityFixedValueFvPatchVectorField
(
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF
)
:
    fixedValueFvPatchField<vector>(p, iF),
    A_(0)
    
    ...

sineVelocityFixedValueFvPatchVectorField::
sineVelocityFixedValueFvPatchVectorField
(
    const sineVelocityFixedValueFvPatchVectorField& ptf,
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF,
    const fvPatchFieldMapper& mapper
)
:
    fixedValueFvPatchField<vector>(ptf, p, iF, mapper),
    A_(ptf.A_)
    
    ...

sineVelocityFixedValueFvPatchVectorField::
sineVelocityFixedValueFvPatchVectorField
(
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF,
    const dictionary& dict
)
:
    fixedValueFvPatchField<vector>(p, iF, dict),
    A_(dict.lookupOrDefault<scalar>("A", 0))
    
    ...

sineVelocityFixedValueFvPatchVectorField::
sineVelocityFixedValueFvPatchVectorField
(
    const sineVelocityFixedValueFvPatchVectorField& ptf
)
:
    fixedValueFvPatchField<vector>(ptf),
    A_(ptf.A_)
    
    ...

sineVelocityFixedValueFvPatchVectorField::
sineVelocityFixedValueFvPatchVectorField
(
    const sineVelocityFixedValueFvPatchVectorField& ptf,
    const DimensionedField<vector, volMesh>& iF
)
:
    fixedValueFvPatchField<vector>(ptf, iF),
    A_(ptf.A_)
    
    ...

void sineVelocityFixedValueFvPatchVectorField::updateCoeffs()
{
    if (this->updated())
    {
        return;
    }

    if (false)
    {
        Info<<"updateCoeffs sineVelocity sha1: 5fbd59f531f5427d360db88650500b0534d5f992\n";
    }

//{{{ begin code
    #line 32 "/home/cfd/work/bc/pitzDaily/0/U.boundaryField.inlet"
            fvPatchField<vector> f
            (
                patch().lookupPatchField<volVectorField, vector>("U")
            );

            const scalar t = this->db().time().timeOutputValue();
            const scalar pi = constant::mathematical::pi;

            forAll(patch().Cf(), i)
            {
                f[i] = vector(A_*sin(2.*pi*t/0.1), 0, 0);
            }

            operator==(f);
//}}} end code

    this->fixedValueFvPatchField<vector>::updateCoeffs();
}

...

これでパラメタ A を指定できるようになる。

0/U

    inlet
    {
        type            sineVelocity;
        A               10.;
        value           uniform (0 0 0);
    }

既存のコードをベースにした実装

既存の境界条件のコードを利用して新しい境界条件を実装する。

$ mkdir derived
$ cd derived
$ cp -r $FOAM_SRC/finiteVolume/fields/fvPatchFields/derived/flowRateInletVelocity sineVelocity
$ cd sineVelocity
$ sed -e "s/flowRateInletVelocity/sineVelocity/g" flowRateInletVelocityFvPatchVectorField.H > sineVelocityFvPatchVectorField.H
$ sed -e "s/flowRateInletVelocity/sineVelocity/g" flowRateInletVelocityFvPatchVectorField.C > sineVelocityFvPatchVectorField.C
$ mkdir Make

Make/files

sineVelocityFvPatchVectorField.C

LIB = $(FOAM_USER_LIBBIN)/libsineVelocity

Make/options

EXE_INC = \
    -I$(LIB_SRC)/finiteVolume/lnInclude \


LIB_LIBS = \
    -lOpenFOAM \
    -lfiniteVolume \

コードの修正は、上述のものと同様。

sineVelocityFvPatchVectorField.H

class sineVelocityFvPatchVectorField
:
    public fixedValueFvPatchVectorField
{
    // Private data

        scalar A_;
	
	...

sineVelocityFvPatchVectorField.H も同様。ただし、以下に注意。

sineVelocityFixedValueFvPatchVectorField::
sineVelocityFixedValueFvPatchVectorField
(
    const fvPatch& p,
    const DimensionedField<vector, volMesh>& iF,
    const dictionary& dict
)
:
    fixedValueFvPatchField<vector>(p, iF, dict), ← dict を追加
    A_(dict.lookupOrDefault<scalar>("A", 0))
{}

"void updateCoeffs(const scalar uniformRho)" はいらないので削除。

void Foam::sineVelocityFvPatchVectorField::write(Ostream& os) const
{
    fvPatchField<vector>::write(os);
    writeEntryIfDifferent<scalar>(os, "A", 0, A_);
    writeEntry("value", os);
}

境界条件のタイプ

境界条件には以下のようなタイプがある。

  • 値指定 (fixedValue 系)
  • 勾配指定 (fixedGradient 系)
  • 上記の混合 (inletOutlet 系)

境界条件によっては、inletOutlet のようにソースファイルがたくさんある場合がある。その場合、以下のような名前を変換するスクリプトを作ったほうがよいかもしれない。

rename

#!/bin/sh
OLD=inletOutlet
NEW=myInletOutlet

for FILE in * ; do
    if [ ! -d $FILE -a $FILE != "rename" ] ; then
        BASE=`echo $FILE | sed -e 's/\..*//'`
        EXT=`echo $FILE | sed -e "s/$BASE\.//"`

        NEWFILE=`echo $FILE | sed -e "s/$OLD/$NEW/g"`
        sed -e "s/$OLD/$NEW/g" $BASE.$EXT > $NEWFILE
    fi
done

変数 OLD と NEW にそれぞれ変換前と変換後の名前を設定し、以下のように実行する。

$ sh rename

inletOutlet の場合、Make/files に指定するのは、"...Field.C" ではなく "...Fields.C" である。Make/files に何を指定すべきかは、もとのコードの Make/files ($FOAM_SRC/finiteVolume の中にある) を見て確かめること。

特定のケース用に境界条件を作る場合

特定のケース用に作った境界条件のライブラリを全ケース共有のディレクトリに置くと管理しにくいので、ケース自体にライブラリを収めたい。以下のようにする。

Make/files

sineVelocityFvPatchVectorField.C

/*LIB = $(FOAM_USER_LIBBIN)/libsineVelocity*/
LIB = ../../libsineVelocity

system/controlDict

libs
(
    "derived/sineVelocity/libsineVelocity.so"
);