グローバルスパース有限要素スティフネスマトリックスでディリクレ境界条件を効率的に実装する方法


9

グローバルスパース有限要素行列のディリクレ境界条件が実際に効率的に実装される方法を知りたいです。たとえば、グローバルな有限要素行列が次のとおりだったとします

K=[5201024100016210700020]と右側のベクトルb=[b1b2bb4b5]

次に、最初のノード()にディリクレ条件を適用するために、最初の行をゼロにし、 1を入れ、右側から最初の列を減算します。たとえば、システムは次のようになります K 11 K = [ 1 0 0 0 0 0 4 1 0 0 0 1 6 3 2 0 0 3 7 0 0 0 2 0 3 ]バツ1=cK11

K=[1000004100016200700020]と右側のベクトルb=[cb22×cb0×cb4+1×cb50×c]

理論的にはこれで十分ですが、K行列が圧縮行形式(CRS)で格納されている場合、列を右側に移動すると、大規模なシステム(ディリクレが多いノード)のコストが高くなります。代替案は、ディリクレ条件に対応する列を右側に移動しないことです。つまり、システムは次のようになります:

K=[1000024100016210700020]と右側のベクトルb=[cb2bb4b5]

ただし、これはシステムが対称ではなくなり、前処理付き共役勾配法(または他の対称ソルバー)を使用できなくなるという大きな欠点があります。私が遭遇した興味深い解決策の1つは、Gennadiy Nikishkovの著書「Programming Finite Elements in Java」で見つけた「Method of Large Numbers」です。この方法は、倍精度には約16桁の精度しか含まれないという事実を利用しています。位置に1を置く代わりに、多数を配置します。たとえば、システムは次のようになります。 K11

K=[1.0e64201024100016210700020]と右側のベクトルb=[c×1.0e64b2bb4b5]

この方法の利点は、スパースストレージフォーマットに対して非常に効率的であると同時に、マトリックスの対称性を維持することです。私の質問は次のとおりです:

ディリクレ境界条件は通常、熱/流体の有限要素コードにどのように実装されますか?人々は通常、大量の方法を使用しますか、それとも他のことをしますか?誰かが見ることができる大きな数の方法に不利な点はありますか?私はこの問題を解決するほとんどの商用および非商用コードで使用される標準の効率的な方法がおそらくあると想定しています(明らかに私は人々がすべての商用有限要素ソルバーのすべての内部の仕組みを知っているとは期待していませんが、この問題は基本的/基本的なようです誰かがそのようなプロジェクトに取り組んでいる可能性があり、ガイダンスを提供できるほどです。


2
これがあなたをかなり遅くしているという証拠はありますか?
ビルバース2015

@BillBarthはい。ただし、私が何かを非効率的に行っている可能性は常にあります。Gennadily自身は、明示的な方法は完全な2D配列に対しては簡単ですが、「行列がコンパクトな形式の場合、行列の行と列にアクセスするのは必ずしも簡単ではない」と書いています。明示的な方法は、効率的に実装するのがより難しい場合があることを示唆しています。私のコードは現在書かれているので、明示的なメソッドは実際の解決よりも時間がかかる場合があります。
ジェームズ

1
Wolfgangが言うようにそれを行い、組み立てる前に要素行列に境界条件を適用します。
ビル・バルト

@BillBarthはい、そうするつもりです。彼のビデオは素晴らしいです!各タイムステップでグローバルマトリックスを再構成する必要があるかどうかについて、彼にコメント/質問を残しました。その後、彼の答えを受け入れます。
ジェームズ

回答:


11

deal.II(http : //www.dealii.org- 免責事項:私はそのライブラリの主要な作成者の1人です)では、行と列全体を削除しますが、全体として高すぎません。秘訣は、スパースパターンが通常対称であるという事実を使用することです。そのため、列全体を削除するときにどの行を調べる必要があるかがわかります。

私の考えでは、これらの行と列をグローバルマトリックスに追加する前に、セルマトリックスのこれらの行と列を削除するのがより良いアプローチです。そこでは完全な行列を扱うので、すべてが効率的です。

私は、多数のアプローチについて聞いたことがなく、ひどく悪条件の問題に確実につながるので、それを使用しません。

参考までに、deal.IIで使用するアルゴリズムは、http://www.math.colostate.edu/~bangerth/videos.htmlの講義21.6および21.65で概念的に説明されています。彼らはあなたの説明と密接に一致します。


2
時間依存の問題(たとえば、熱方程式)の場合、タイムステップごとにグローバルマトリックスを再構成しますか?私が尋ねる理由は、ゼロ以外のディリクレ条件の場合、右側を変更するときに元のグローバル行列からの情報が必要ですが、前のタイムステップ中にこれらの列をゼロにした場合、この情報は失われます(保存しない限り)追加のアレイ)。グローバルマトリックスがタイムステップごとに再構成されている場合、これは問題になりません。これは、私が検討していることであり、アダプティブメッシュを使用する場合はとにかく何をしなければならないかです。
ジェームズ

1
それはアプリケーションに依存します。すべての「ビッグ」コードは、非線形の時間依存問題を解決します。これらについては、何らかの方法で再構成する必要があることは明らかです。線形コードの場合、元の行列を保存し、ステップごとに別の場所にコピーして境界条件を適用してから、ソルバーでそれを使用できます。これはより多くのメモリを必要とするだけですが、それ以外は安価です。
Wolfgang Bangerth 2015

1
ああ、それは私が疑っていたものだと思います。あなたが提案したように私は実装します。わかりました。助けてください。これらのdealliiチュートリアルビデオは本当に良いです!
ジェームズ

2

ゼロBCは簡単です。非ゼロBCの場合は、ラグランジュ乗数も使用できます。たとえば、こちらをご覧ください。LMの利点の1つは、任意の制約方程式を使用できることですが、システムが不明確になるため、適切なソルバーが必要です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.