LoginSignup
5
3

More than 5 years have passed since last update.

OpenFOAMとfoam-extendの異なる部分のメモ(随時追加)

Last updated at Posted at 2016-08-30

定数

OpenFOAM/foam-extendでは数値計算用定数は

e          // M_E
pi         // M_PI
twoPi      // 2*M_PI
piByTwo    // 0.5*M_PI

で定義されています。注意しておきたいのは、OpenFOAMとfoam-extendで定数が所属する名前空間が異なる点です。OpenFOAMは

Foam::constant::mathematical

で、foam-extend-3.2は

Foam::mathematicalConstant

です。

autoPtr

OpenFOAM/foam-extend-3.2の提供するスマートポインタであるautoPtrのコンストラクタに微妙な違いがあります。OpenFOAMのautoPtrには

template<class T>
inline Foam::autoPtr<T>::autoPtr(const autoPtr<T>& ap, const bool reUse)

がありますが、foam-extend-3.2にはありません。したがって、自作クラスのコピーコンストラクタにおいてautoPtrをcloneさせたい場合、OpenFOAMでは

Foam::myClass:myClass(const myClass& mc)
:
    myPtr_(mc.myPtr_, false)
{}

とすればいいのですが、foam-extend-3.2の場合はわざわざ

Foam::myClass:myClass(const myClass& mc)
:
    myPtr_(NULL)
{
    if (mc.myPtr_.valid())
    {
        myPtr_.set(mc.myPtr_->clone().ptr());
    }
}

とする必要があります。

Listのメンバ関数:append

OpenFOAMには

OpenFOAMのListクラスのappend
void append(const T&);
void append(const UList<T>&);
void append(const UIndirectList<T>&);

が用意されていますが、foam-extend-3.2には

OpenFOAMのListクラスのappend
void append(const UList<T>&);
void append(const UIndirectList<T>&);

しか用意されていません。したがって、Listの最後にT型オブジェクトを加えたいとき、OpenFOAMは

OpenFOAM
label i = 1;
labelList plainList;
plainList.append(i);

とできるのですが、foam-extendの場合はresizeを使って

foam-extend
label i = 1;
labelList plainList;
plainList.resize(plainList.size() + 1, i);

とする必要があります。ただし可変長配列として定義されたDynamicListがありますので、オブジェクト化時点でサイズが不明な場合はDynamicListを使うことをお勧めします。(DynamicListの場合は、OpenFOAMとfoam-extendの両方共にappend(const T&)が用意されています。)

OpenFOAM,foam-extend共通
label i = 1;
DynamicList<label> dynList;
dynList.append(i);

このようにDynamicListへ追加を繰り返し、最終的にサイズが決まったところでDynamicListをListに変換するというのが正しい使い方と思われます。つまり

DynamicList-->Listへの変換(コピーではなくポインタの所有権移動)
DynamicList<label> dynList;
...                                   // 要素の追加
labelList plainList(dynList.xfer());  // List<T>へ変換

xferについてはXfer<T> Classを参照してください。

fvPatchのメンバ関数:start

OpenFOAMのfvPatchは、patchが始まる面のlabelを返すstart関数がありますが、foam-extendにはありません。OpenFOAMのfvPatch::start()はpolyPatch::start()のwrapperなので、foam-extendの場合はpolyPatchに直接アクセスする必要があります。

OpenFOAM
const label patchI = 0;
const fvBoundaryMesh& fvBMesh = mesh.boundary();       // meshはfvMeshオブジェクト、fvBoundaryMeshを取得
const fvPatch& fvp = fvBMesh[patchI];                  // fvPatchが返ってくる
const label start = fvp.start();
foam-extend
const label patchI = 0;
const polyBoundaryMesh& pBMesh = mesh.boundaryMesh();  // meshは上と同様fvMeshオブジェクト、polyBoundaryMeshを取得
const polyPatch& pp = pBMesh[patchI];                  // polyPatchが返ってくる
const label start = pp.start();

fvBoundaryMeshのメンバ関数:findPatchID

OpenFOAMのfvBoundaryMeshにはpatchIDを探して返すfindPatchID関数がありますが、foam-extendにはありません。どちらもpolyBoundaryMeshにfindPatchIDがありますので、foam-extendの場合はpolyBoundaryMesh::findPatchIDを呼び出すことになります。

fvPatchMapper

OpenFOAMの場合

unmapped faceがあった場合、そのface IDのaddressingは

  • direct = true --> -1が与えられる。
  • direct = false --> labelListはゼロサイズ

となり、さらにhasUnmapped=trueとなります。したがって、fvPatchのautoMap関数内で新たにPatchに追加されたfaceの値を初期化しようとする場合、下記のようなコードとなります。

OpenFOAM
void myFvPatchField::autoMap(fvPatchFieldMapper& m)
{
    ...
    if (!m.hasUnmapped())
    {
        return;
    }

    if (m.direct())
    {
        // direct addressingの場合
        const labelList& addr = m.directAddressing();

        forAll(addr, newFaceI)
        {
            // direct addressingの場合、unmapped faceの値は-1になっている
            if (addr[newFaceI] == -1)
            {
                ... // newFaceIに対応するfieldの値の初期化
            }
        }
    }
    else
    {
        // indirect addressingの場合
        const labelListList& addr = m.addressing();

        forAll(addr, newFaceI)
        {
             const labelList& addrI = addr[i];

             // indirect addressingの場合、unmapped faceのlistはゼロサイズになっている
             if (addrI.size() == 0)
             {
                 ... // newFaceIに対応するfieldの値の初期化
             }
        }
    }
}

foam-extendの場合

unmapped faceがあった場合、そのface IDのaddressingは

  • direct == true --> 0が与えられる
  • direct == false --> labelListのサイズは1、labelは0が与えられる

となります。さらにfoam-extendの場合メンバ関数hasUnmapped()が用意されていません。したがって、fvPatchのautoMap関数内で新たにPatchに追加されたfaceの値を初期化しようとする場合、下記のようなコードとなります。

foam-extend
void myFvPatchField::autoMap(fvPatchFieldMapper& m)
{
    ...
    if (m.direct())
    {
        // direct addressingの場合
        const labelList& addr = m.directAddressing();

        forAll(addr, newFaceI)
        {
            // direct addressingの場合、unmapped faceの値は0になっているので
            // face ID = 0のfaceに対して初期化を実行するか否かの判定が必要。
            // 新たなfaceは常にfvPatchリストの末尾に追加されるので
            // m.sizeBeforeMapping() == 0のとき以外はface ID = 0の値を初期化
            // する必要はない。
            if
            (
                (addr[newFaceI] == 0 && newFaceI != 0)
             || m.sizeBeforeMapping() == 0
            )
            {
                ... // newFaceIに対応するfieldの値の初期化
            }
        }
    }
    else
    {
        // indirect addressingの場合
        const labelListList& addr = m.addressing();

        forAll(addr, newFaceI)
        {
            const labelList& addrI = addr[i];

            // indirect addressingの場合もdirect addressingと同様の判定が必要
            if
            (
                (
                    addrI.size() == 1
                 && addrI[0] == 0
                 && m.sizeBeforeMapping() != 0
                )
             || m.sizeBeforeMapping() == 0
            )
            {
                ... // newFaceIに対応するfieldの値の初期化
            }
        }
    }
}
5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3