OpenCFDは、2022年12月にOpenFOAM® v2212をリリースすることを発表します。このリリースでは、コードの多くの領域でOpenFOAM-v2206の機能を拡張しています。新機能は、OpenCFDのお客様がスポンサーとなった開発、内部資金による開発、OpenFOAMコミュニティからの機能および変更の統合を表しています。
OpenFOAMは、OpenCFDによってGPLライセンスの下で配布されています。様々なLinuxや他のPOSIXシステムでのコンパイルに適したソースコードパッケージに加え、このリリースでは、コンパイル済みのバイナリパッケージも多数用意されています。
Ubuntu Linux: Ubuntu 22.04 (LTS), 20.04 (LTS), 18.04 (LTS), 22.10 用のパッケージインストール。
openSUSE Linux: Leap15.4、Leap15.3用パッケージインストール。
Redhat Linux variants: CentOS/Rocky 8, 7 および Fedora 37, 36, 35, ...用のパッケージインストール。
Windowsユーザは、プリコンパイルされたパッケージについて、3つのオプションがあります(詳細)。
Windows Subsystem for Linux(Ubuntu、openSUSEなどベース)を使用する。
クロスコンパイルされたネイティブな実行ファイル
dockerによるインストール
OpenFOAMのコンテナサポートは、プリ・アセンブルされたイメージではなく、記述ファイルによって提供されます。
パッケージング/コンテナ参照
Mac OSXユーザーは、ソースからコンパイルするか、コンパイル済みのパッケージのDockerコンテナを使用するかのオプションがあります(詳細)。
v2212 User Upgrade Guide
行動の変化
timeActivatedFileUpdate(タイムアクティベートファイルアップデート
timeActivatedFileUpdate では、ファイルが見つからない場合、Critical エラー (FatalIOError) として扱われるようになりました。以前は単純なエラー (FatalError) として扱われ、functionObject をロードするときのみ Warning にダウングレードされ、設定エラーに気づかないことを意味しました。
Spalart-Allmaras DESモデル
SpalartAllmarasベースのDESモデルでは、以前アクティブであったft2項はデフォルトで非アクティブになりました。その活性化は、新しいオプションのft2項(デフォルトではfalse)を使って管理することができます。
Input Dictionaries
力、力係数
binModels、forceの優先順位をより一貫して取り扱うようにしました。ディクショナリーがオーバースペックな場合、CofR ショートカットよりも高い優先順位を coordinateSystem エントリーに与えるようにしました。
合理化改善
流線形の取り扱いの一部がさらに改良されました(例:補間におけるx/y/zの代わりにバリセントリック座標)。その過程で、入力要件が緩和されました。
- デフォルトのトラッキング方向は'forward'です。
- U(速度)フィールドはサンプリングされたフィールドに名前を付ける必要がありません。
座標系の扱いを改善
座標系定義がサブディクショナリースコープ内に組み込まれている場合、原点キーワードはオプションになりました。例えば
dict1
{
coordinateSystem
{
origin (0 0 0); // now optional here
rotation ...;
}
}
しかし、サブディク トなしで構築された場合は、必須であることに変わりはない。例えば
dict2
{
origin (0 0 0); // still mandatory
e1 (1 0 0);
e3 (0 0 1);
}
この変更により、transform サブディクショナリはより自然に記述できるようになりました。
formatOptions
{
vtk
{
scale 1000; // m -> mm
transform
{
rotationCentre (1 0 0);
rotation axisAngle;
axis (0 0 1);
angle -45;
}
}
}
ヒストグラムの非推奨項目
setFormat と formatOptions の項目は,ヒストグラム関数オブジェクトから静かに非推奨とされました.
ユーティリティの推移
transformPointsとsurfaceTransformPointsのオプション名を更新しました。
新しいオプション -auto-centre と -centre は、それぞれ -auto-origin と -origin を置き換えます(古いオプションも互換性のあるエイリアスとしてまだ受け入れられます)。centerre に変更することで、座標系 origin() との意味の混同を避けることができます。
effectivenessHeatExchangerSource
The effectivenessHeatExchangerSource
fvOption has been renamed to heatExchangerSource
. Its previous behaviour can be recovered by using the heatExchangerSource
with the submodel of effectivenessTable
.
histogram
ヒストグラム関数オブジェクトがリファクタリングされました.以前の動作は,equalBinWidthのサブモデルでヒストグラムを使用することで回復できます.また,タイムステップごとの出力ファイルが1つの出力ファイルに置き換えられました.
v2212 Developer Upgrade Guide
潜在的な破壊的変化
ツリーデータ項目
Octree 処理への更新の一部として、様々な treeData アイテムは、データの完全または部分的なサブセットを一貫して処理するようになりました。この結果、直接アクセスメソッドである cellLabels(), faceLabels(), edgeLabel() を使用するコードは、おそらく破損します。
- 要素をサブセットせずに treeData xxxLabels() メソッドを使用することは常に安全ではありませんでした。しかし、様々なクラス (treeDataCell, treeDataEdge, etc) が自動的に ID ルックアップを提供するため、この問題は明らかではありませんでした。
- 元のインデックスへの参照を安全に解除するには objectIndex(label) を、元のオブジェクトへの参照を解除するには operator[](label) を使用します。treeDataEdge では、幾何学的データを取得するために line(label) 便利なヘルパーがしばしば好まれます。
オプションの辞書 readEntry
いくつかの特殊なケースでは、辞書のreadEntryをオプションにすると便利なことがある。たとえば
dict.readEntry("key", keyType::LITERAL, false);
// Same as
dict.readIfPresent("key", keyType::LITERAL);
しかし、boolean引数はしばしば管理が混乱し、その意味を思い出すためにドキュメントを参照する必要があります。時には、(true|false|maybe) という非二項対立の論理を扱いたいこともあります。これを管理するために、軽量な IOobjectOption というオプションの束が導入され、IOobject からもアクセスできるようになりました。これにより、以前の readEntry は次のように変形します。
dict.readEntry("key", keyType::LITERAL, IOobject::READ_IF_PRESENT);
デフォルト以外のオプションを持つreadEntryが稀であることから、この変更によって既存のユーザーコーディングが大きく崩れることはないと思われます。
ISstreamへのストリームリネームの制限
- non-constアクセスは、以前はトップレベル(IOstream)で宣言されていたため、ファイルを開いた後にOFstream::name()などを変更することが可能で、開いた基礎ファイルと矛盾が生じることがありました。 名前の変更をISstream(およびITstreamのカウンターパート)に制限するようにしました。既存の有効なコードには影響を与えません。
非推奨のメソッド
PtrList::operator()(label)
PtrList::operator()(label) メソッドは対応するリストアイテムへの const ポインタを返します。これは,コーディングの意図をより明確に表現する他のアクセスメソッドでも同様に行うことができます.
- get(label) : 一意性ptrと同じネーミング
- set(label) : 伝統的なチェックの名前ですが、視覚的に2パラメータ版と混同されることがあります。
- test(label) : bitSet, boolList, labelHashSet に準じた命名。
writeFile
createFile メソッドは、以下の理由で非推奨となっています。
newFileAtTime(const word&, scalar)
: same withcreateFile(const word&, scalar)
newFileAtStartTime(const word&)
: same withcreateFile(const word&)
ベースクラス/コンテナの改良
General
メソッド名をより親しみやすいSTLメソッド名に揃える最初の取り組みです。これにより、名前の親しみやすさが増し、異なるC++コードベース間で移植する際に役立つことがあります。
- std::vector との類似性を調整したリストコンテナ
- front(), back() methods
- push_back() method for containers that already had append().
- pop_back() method
- LinkedList コンテナ。std::list との類似性を調整。
- front(), back(), push_front(), push_back(), pop_front() methods
Foam::string and Foam::fileName
C++23 std::string に追加されるのと同じメソッドに相当する、新しい string::contains() コンビニエンスメソッドを追加しました。例えば
if (keyword.contains('/')) ...
if (keyword.find('/') != std::string::npos) ...
いくつかのfileNameメソッドが追加され、std::filesystem::pathとの類似性が調整されました。
- stem(), replace_name(), replace_ext(), remove_ext() etc
PtrList
PtrList::get(label) と PtrList::set(label) メソッドは内部境界チェックを含むようになり,境界外へのアクセスに対しては nullptr を返すようになりました.この追加チェックは些細なオーバーヘッドですが、HashPtrTable や autoPtr などと対称的な get() のフェイルセーフな振る舞いを提供し、UPtrList、PtrList、PtrDynList の set(label) メソッドを整列させることができるようになりました。
HashPtrTable
HashPtrTable のセットメソッドが refPtr/tmp をサポートするようになり、さらに柔軟性が増しました。
FixedList
テンプレート化された get<unsigned>() メソッドが追加され、FixedList のコンパイル時のインデックス付けが高速になりました(インデックスが無効な場合はコンパイラエラーが発生します)。これにより、noexceptアクセスが可能になり、他の様々な用途(例えば、triFace、triPoints、...)に伝播することができるようになった。
MinMax
- MinMax コンテナで、シングルまたはダブル・パラメータを取る reset() メソッドがサポートされるようになりました。これは、フル・リセットの後に add() を実行するよりも便利です (そして、わずかに効率的です)。
- オーバーラップ(overlaps)と同様に動作するが、両端の排他的チェックを行うMinMax intersects()クエリを追加しました。
- 新しい MinMax::operator&=() は、2つの最小-最大範囲の和を実行します。この演算子は、intersects()クエリと名前が似ていて紛らわしい、未使用のintersect()メソッドを置き換えるものです。
IOstreams
OFstreamのアトミックファイル作成に対応
IOstreamOption::ATOMIC 列挙は、OFstream を構築する際のディスパッチタグとして使用することができます。この形式では、書き込みのための中間ファイルが作成されます。ストリームが閉じられるときだけ、この中間ファイルは実際の出力名に移動/リネームされます。これにより、ファイルの書き込み中にシミュレーションがクラッシュした場合でも、部分的なファイル(破損したファイル)を避けることができ、安全です。名前の最後を~tmp~とすることで、OpenFOAM内でバックアップファイルとして扱われ、再起動時にはロードされないようになります。
列挙された追記・非追記オープンファイル
- IOstreamOption::APPEND と IOstreamOption::NON_APPEND の列挙を使用すると、boolean パラメータよりも明確である。既存のユーザーコーディングに影響を与えることはないだろう。
簡略化されたストリームコンストラクタ
- IOstreamOption の導入 (OpenFOAM-v1806 で追加) により、トップレベルストリーム (例: IFstream, OFstream) が内部 IOstream の「バージョン」 (例: version: 2.0) についての追加情報を必要とするケースがなくなったため、これらのコンストラクタ形式が削除されました。 これにより、指定したフォーマット/圧縮/付加の組み合わせでファイルを開くことができ、バージョンの指定に煩わされることがなくなります。
IOobjectOption, IOobject
IOobjectの作成は、通常、次のような内容です。
IOobject io
(
"foo",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false // do not register
);
末尾の "do not register "コメントは、呼び出しパラメータが実際には自己文書化されていないことを示しています。典型的なオプションは IOobjectOption のセットで列挙されるようになった。register/no-register が適切に列挙されるようになったので、このような呼び出しができるようになった。
IOobject io
(
"foo",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
また、様々なオプションは、明示的または暗黙的にバンドルすることができる。
IOobject io
(
"foo",
runTime.timeName(),
mesh,
{ IOobject::MUST_READ, IOobject::NO_REGISTER }
);
IOobjectOption
IOobjectOption クラスは、objectRegistry などに依存しない軽量な処理のために、読み取り/書き込み、ストレージフラグをカプセル化しています。また、辞書の読み込みのための読み込み制御情報を提供するために使用することができ、さらなるサブ依存を導入することはありません。
- isReadRequired() と isReadOptional() のために IOobjectOption (または IOobject) クエリを追加しました。これらは MUST_READ, MUST_READ_IF_MODIFIED, READ_IF_PRESENT のテストをカプセル化し、利便性と散らかりにくさを実現しています。例えば
if (isReadRequired() || (isReadOptional() && headerOk()))
{
...
}
むしろ長く、繰り返される形。
if
(
(
readOpt() == IOobject::MUST_READ
|| readOpt() == IOobject::MUST_READ_IF_MODIFIED
)
|| (readOpt() == IOobject::READ_IF_PRESENT && headerOk())
)
{
...
}
きめ細かな辞書の読み込みを可能にするIObjectOption
以前は、辞書エントリーの読み取りを高度に制御するための 'mandatory' (bool) がありましたが、呼び出し側のコードでは追加のコードコメントがないと意味が不明でした。
IOobjectOption::readOption を代わりに使用することで、さらなるオプション (たとえば NO_READ) が可能になり、true/false の bool フラグよりもコード内の目的がより明確になります。
これはマイナーなブレークダウンです(使用頻度が低く、高度な使用法のみ)
ジオメトリ処理の改善・最適化
このバージョンでは、幾何学的な実体を扱う際に便利なメソッドが多数追加されています。
General
- ヘッダ定義の統一やパススルー方式の増加により、四面体や三角形の取り扱いを簡素化しました。
- triFace / triangle などの一貫したメンバアクセス。頂点/点に a(), b(), c() のようにアクセスできる。
- 三角形に、よく使われる計算のための静的な center() と areaNormal() および unitNormal() メソッドが追加されました。
box()
meshShapes (cell,edge,face,triangle,...) に、Pair<point> を返す低レベルの bound box() メソッドを追加しました。これらの抽出された幾何学的限界は、boundBoxに依存することなく使用することができます。
mesh cellBb()
primitiveMesh cellBb()メソッドを追加しました。これは、最も安価な計算を使用して、指定されたメッシュセルのバウンドボックスを返します。
- は、すでに利用可能であれば、cellPoints を使用する。これは、最小/最大比較の回数が最も少ないからである。
- またはセル面を歩く:セルボックス()メソッドを介して、需要駆動型のセルポイントなどを作成しないようにします。
patch sphere(facei)
PrimitivePatchに、与えられたパッチ面を囲む外接球(原点+半径の2乗)を返すsphere(facei)メソッドを追加しました。
ベクター方式の追加
ジオメトリを扱う場合、点の比較は非常に頻繁に発生します。これらは Foam::vector 内の直接メソッドとしてバンドルされるようになりました。
- mag() : ベクトルの長さ (L2-ノルム)を指定します。
- magSqr() : ベクトルの長さ(L2-norm)の二乗。
- dist(const vector&) : 別のベクトルからの L2 ノルムの距離
- distSqr(const vector&) : 別のベクトルからの L2 ノルムの距離の二乗を返します。
これらの方法は、より簡潔で、中間的な変数を避けることができます。例えば
if (a.distSqr(b) < tol) ...
// vs.
if (magSqr(b - a) < tol) ...
新しい vector::less_xyz() vector::less_yzx() および vector::less_zxy() 比較メソッドは、辞書式ソートに便利です。
boundBox()、treeBoundBox()の処理。
boundBox()、treeBoundBox()クラスを若干整理し、以下のように一部拡張しました。
- 追加の構築およびリセット・メソッド。
- null() 静的メソッド : invertedBoxへのconst参照として(適切なキャストで)。
- grow() メソッド : ボックスを絶対量だけ拡張します。
- inflate(random) : treeBoundBox::extend のインプレース版。
- boundBox::hexCorners(), boundBox::hexFaces() : hexCell に対応する点/面を明確に指定するためのものです。
- boundBox::addは、プリミティブメッシュ形状から抽出されたエッジや「ボックス」を追加するときに、点のペアを使用します。
オクツリーの改良
ループ内でのメモリ効率を上げるため、結果を外部記憶するオクツリー findBox(), findSphere() を追加しました。単純なテストでは、octree overlaps() を使用することができます。これは、findBox(), findSphere() と同様に動作しますが、いずれかの形状が重なり合った場合、早期に終了します。
treeDataの改良
サブセットとインターフェースの全体的な整合性を向上させるための変更。
- サブセット/非サブセットのバージョンを確実に堅牢に処理するために、統一された内部ゲッターを持つサブセット/非サブセット・コレクションの使用を拡張してください。
- 演算子と objectIndex(label) で、サブセットの有無にかかわらず、基礎となる項目、つまり元のインデックスに標準的にアクセスできるようになります。
- centres()とcenter(label)は、代表的な点群情報である。
- nDim() はオブジェクトの次元数 (0: 点、1: 線、など) を返す。これらは、それぞれの形状がどの程度「太い」のか、また bounds(labelList) が何らかの有用な情報を提供するかどうかを判断するために使用される。
- bounds(labelList) は、特定のアイテムに必要な完全なバウンドボックスを返します。例えば、様々な3Dセルに対する全体的な境界。
- 静的ヘルパー : boxes() と bounds()
MPI(Pstream)メソッドの更新
このリリースでは、より多くのケースでネイティブMPIルーチンが使用されるようにコードの調整が行われていますが、一部のPstream(MPI)メソッドを簡素化するための変更も含まれています。
- ルーチンの呼び出しを簡素化するために、いくつかの UPstream メソッドに内部 parRun ガードを追加しました。
- MPIリダクションのネーミングをより一貫したものにしました。
ユニファイドネーム | 旧名称 |
---|---|
combineReduce | combineAllGather |
listCombineReduce | listCombineAllGather |
mapCombineReduce | mapCombineAllGather |
ダイレクトMPIおよび/またはリダクション
MPI_LAND および MPI_LOR intrinsics のダイレクトラッパーとして UPstream::reduceAnd および UPstream::reduceOr が追加されました。これらは、論理演算のための特別な目的の returnReduce で再利用されます。
MPI bool オペレーションを使用すると、ベンダー/ハードウェアによる MPI の最適化が可能になります。
returnReduceAnd(bool) と returnReduceOr(bool) をそれぞれ andOp<bool>() と orOp<bool>() 演算子を持つ returnReduce のインライン・ラッパーとして使用すると、より簡単に扱える式が得られます。また、パラメータをブール値に一義的にキャストできるという利点もあります。
これらの新しいコールの例をいくつか紹介します。
- 任意のランクに存在するかどうかをテストする。
if (returnReduceOr(list.size()) { ... }
if (returnReduceOr(!list.empty()) { ... }
- すべてのランクで非存在をテストする。
if (returnReduceAnd(list.empty()) { ... }
if (!returnReduceOr(list.size()) { ... }
globalIndexの修正
リーディングディスパッチタグを使用し(他のC++の規約との類似性を高める)、マスターデータを別々に書き込むことができるgather/writeに便利なgatherNonLocalタグを含めます。
- clear()メソッドを追加し、NULL構築状態にリセットするようにした。
- PatchTools::gatherAndMergeは、出力パラメータとしてglobalIndexの回収をサポートします。これは、後続のフィールドマージ操作での再利用を可能にします。
- PatchTools::gatherAndMerge にオプションのパラメーターとして pointMergeMap が追加されました。この情報は常に必要というわけではありません。例えば、gatherAndMergeを使用して面を結合するだけで、ポイントフィールドを使用しない場合です。
メッシュ/パッチへのアクセス方法を改善しました。
メッシュとフィールドコンポーネントのアドレスには、細かいですが様々な便利な変更があります。
FieldFieldへのインデックス作成
FieldFieldへのタプル(ペア)インデックスをサポートします。(patchi, elemi) のペアを使用して、FieldField の要素にアクセスできるようになりました。
faPatch/fvPatch patchField, lookupPatchField の呼び出しを簡素化。
2番目の(unsed)テンプレートパラメータは完全にオプションになりました。以前は古いコンパイラ(2008年以前)では必要でした。
拡張polyBoundaryMeshパッチ/フェースクエリ
whichPatchFace() メソッドは (patchi, patchFacei) タプルを返し、 whichPatch() は whichPatchFace() の簡略化されたラッパーになりました。
新しいgroupNames()メソッドは、ゾーンと同様のパッチベースの機能を提供します。
拡張された有限領域メッシュ/面クエリ
有限面積から体積メッシュへの対応のためのブックキーピングを改善する。
- whichPolyPatches() = areaMeshに関連するポリパッチ。 これは、パッチ固有のコンテンツを事前に計算(およびキャッシュ)する際に役立ちます。
- whichPatchFaces() = faceLabelsのそれぞれに対応するポリパッチ/パッチフェース。 これにより、より便利な検索が可能になり、リストはエリアメッシュ上にキャッシュされるため、whichPatch() などの呼び出し回数が減ります。
- whichFace() = 与えられたメッシュ面に対応する領域面
また、ボリュームからエリアへのマッパー機能を拡張し、より柔軟で一貫性のあるものにしました。
GeometricFieldのフィールド変更
GeometricField::internalFieldRef() は boundaryFieldRef() や primitiveFieldRef() と同じように書き込みができるようになりました。名前付けは internalField() を補完するものです。
意味は GeometricField::ref() メソッドと同じですが、より明示的な名前がついており、例えば tmp::ref() と混同される可能性は低くなっています。
座標系
座標系に対する基本的な変更はありませんが、coordinateSystem辞書検索に対する取り扱いが単純化されました。coordinateSystems::NewIfPresent()メソッドは、オプショナルな項目の取り扱いを非常に単純化しています。たとえば
coordSysPtr_ = coordinateSystem::NewIfPresent(mesh, dict);
旧来の長いフォームの代わりに
if (dict.found(coordinateSystem::typeName, keyType::LITERAL))
{
coordSysPtr_ =
coordinateSystem::New
(
mesh_,
dict,
coordinateSystem::typeName
);
}
else
{
coordSysPtr_.reset();
}