定数
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には
void append(const T&);
void append(const UList<T>&);
void append(const UIndirectList<T>&);
が用意されていますが、foam-extend-3.2には
void append(const UList<T>&);
void append(const UIndirectList<T>&);
しか用意されていません。したがって、Listの最後にT型オブジェクトを加えたいとき、OpenFOAMは
label i = 1;
labelList plainList;
plainList.append(i);
とできるのですが、foam-extendの場合はresizeを使って
label i = 1;
labelList plainList;
plainList.resize(plainList.size() + 1, i);
とする必要があります。ただし可変長配列として定義されたDynamicListがありますので、オブジェクト化時点でサイズが不明な場合はDynamicListを使うことをお勧めします。(DynamicListの場合は、OpenFOAMとfoam-extendの両方共にappend(const T&)
が用意されています。)
label i = 1;
DynamicList<label> dynList;
dynList.append(i);
このようにDynamicListへ追加を繰り返し、最終的にサイズが決まったところで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に直接アクセスする必要があります。
const label patchI = 0;
const fvBoundaryMesh& fvBMesh = mesh.boundary(); // meshはfvMeshオブジェクト、fvBoundaryMeshを取得
const fvPatch& fvp = fvBMesh[patchI]; // fvPatchが返ってくる
const label start = fvp.start();
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の値を初期化しようとする場合、下記のようなコードとなります。
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の値を初期化しようとする場合、下記のようなコードとなります。
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の値の初期化
}
}
}
}