非構造化セル中心FVM CFDコードに適したデータ型は何ですか?


12

非構造化セルベースの有限体積CFDでのセルブラウジングの効率的なデータ構造に関するアドバイスに興味があります。

ドルフィン cfdコードで)遭遇した1つの例は、このようになります(関連するセグメントを表示します) したがって、各セルの面の数が格納される配列NFacesがあります。次に、ローカルからセルへの面番号をグローバルな面番号にマップするCFace配列。

\ begin {listing} do ip = 1、Ncel ... do j = 1、NFaces(ip)k = CFace(ip、j)ipp = Face(k)%cell1 inn = Face(k)%cell2 if(inn > 0)その後!internal \ end {listing}

コードは面ベースであるため、Face(k)%cell1とFace(k)%cell2の間にある2つのセルのシリアル番号を格納する面データ型があります。

これについてのコメントや代替アプローチの提案を歓迎します。

回答:


9

表示する構造は一般的な選択であり、境界面のゴーストセルを特別な場所に配置して、CSRマトリックス形式でセル面隣接を保存するのと同等です。ただし、FVメソッドは、各顔が一度だけ訪問される顔トラバーサルで完全にまたはほぼ全体で構成されるように定式化できることに注意してください)。セルベースのトラバーサルを使用して、スパースマトリックスの「対角線」より下にある2つのセルをスキップすることで「偽造」できますが、一般的な代替方法は、(leftCell, rightCell) = support(face)、この場合、面はファーストクラスのエンティティになります。通常、面の直交点(重心)、面の法線を保存する場所が必要なため、これは便利です。再構成パーツ(最小二乗など)を顔ベースのデータ構造に配置することもできます。フェイストラバーサルはすべてのサイズが規則的であるため、ベクトル化に適しているように見えますが、出力が重複しているため、トラバーサルを整理して内部ループに入れないようにする必要があります。このより顔向きのデータ構造では、顔の連続的なトラバースを使用して各境界条件タイプを適用できるように、顔番号を並べるのが自然です(ベクトル化にも対応)。

このデータ構造を選択する場合、トラバースがキャッシュ内のセルデータを可能な限り再利用するように、面をソートすることを忘れないでください。顔の順序と関連する最適化のパフォーマンス分析については、PETSc-FUN3Dのいずれかの論文を参照してください。


面をループする場合は、フラックスを計算するためにleftCellおよびrightCellから情報を取得する必要があります。たとえば、面1にはleftCell 1およびrightCell 10、面2にはleftCell 6およびrightCell 31などがあります。 。どのようにベクトル化に対応しますか?
クリス

上記のように(およびPETSc-FUN3Dの論文で説明されているように)、キャッシュを再利用するために顔を注文します。結果は、各面が1回だけアクセスされる「片側」セルトラバースのようなものです。
ジェッドブラウン

3

私はこの質問にすでに答えていることを知っていますが、OpenFOAM C ++ライブラリに実装されている同様の片面ベースのループストレージがあります:

各セルのcellListにはインデックス(ID)があります。「face internal owner」および「face neighbour」という2つのリストがすべての顔に対して定義されています。両方の面リストの長さは、メッシュの内部面の数に対応しています。顔の所有者は、cellListのIDが小さいセルになります(顔の隣の反対側)。境界面は最後に書き込まれ、外向きの法線(ソリューションドメインから)を持ち、もちろん所有者セルは1つだけです。顔領域の法線は、所有者セルから隣接セルに向かって外向きに見えるように方向付けられています。

これは、フラックス計算などに適しています。フラックスは面ごとに1回評価され、所有者セルの合計面の合計に加算され、隣接セルから差し引かれます(合計/差し引きは、面領域の法線の方向に基づいて決定されます)。境界面はソートされ、顔リストの下部に保存されるため、境界条件を顔リストのスライス(境界パッチの開始ラベル、終了ラベル)として定義できるため、境界条件の実装も簡素化されます。境界条件の更新プロセスの効率を高めるためです。これは、内部フェースでの操作によって提供されるソリューションに依存しているためです。

境界面はパッチに凝集されるため、プロセス間通信は結合(プロセッサ)パッチ用に定義され、事前定義されます。つまり、境界メッシュ上でループが発生すると、トップレベルのアクセス関数はラップされたMPI呼び出しを呼び出し、上記のフェイスベースの接続に依存している場合、そのようなコードを「自動的に」並列化します。


問題ありません。この説明が誰かに役立つことをうれしく思います。.:) OpenFOAMでも働いていますか?
tmaric

過去に少しだけ使っていました。私は一般的に、受け入れられている傾向から離れて、車輪を再発明しようとする傾向があります。それが私のタオです。
ジョントラボルタ

1
あなたのタオは、コンピュータサイエンスのタオの反対です:「車輪を再発明しないでください」。しかし、私はそれを理解することができます、最初から何かをすることは魅力的です!:)
tmaric
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.