この記事は、拡散反応方程式系の有限要素法の独自の実装(ソルバージョーカーFEM )に特化しています。
通常、既製のソリューションを使用することをお勧めしますが、問題に特定の機能がある場合は、単純なライブラリに基づいて、タスクを解決するのが簡単です。
はじめに
有限要素法[1-4]は、数理物理学、連続体力学の問題を解決するための効果的な方法のグループです。 FEMプログラミングの質問は、ソース[5–9]に当てられています。
問題の声明
システムのロビン境界値問題 限られた領域での拡散反応方程式 ボーダー付き :
ここに 、 外部法線のベクトルは 。
弱い表現
それぞれを掛ける 任意のテスト関数の方程式 、取得したアイデンティティを統合します 、グリーンの式を適用し、境界条件を考慮します。 ゲット
機能的なソボレフ空間を紹介します 。 機能 これらの恒等式が任意のテスト関数に当てはまる場合、元の境界値問題の弱解と呼ばれます 。
弱い表現は次のように書くことができます:関数を見つける そのような
どこで -バイリニア形式、 -線形形式:
FEMアルゴリズム
宇宙で紹介します 有限次元部分空間 。 ガラーキン法によると、離散問題に到達します:関数を見つける そのような
させる -基礎 。 入れたら 、 、それから問題はSLAE 不明 :
または
部分空間の最も単純な例 -連続的な区分的線形関数の空間。 面積 有限要素(通常は三角形)に分割され、各三角形の関数 線形。 FEMでは、基底関数は、ほとんどの領域でゼロになるように選択され、SLAE行列には多くのゼロがあります。 基本機能として 1つのグリッドノードで1、残りのノードで0に等しい「ピラミッド」を取得します。 各グリッドノードには独自の基底関数があり、ディメンション 部分空間はグリッドノードの数に等しくなります。
ことに注意してください そして ノードがエッジで接続されていない場合、 、 、したがって、合計すると インデックスのみを反復処理するのに十分 その間 そして 番目のノードはエッジを 。
したがって、有限要素法による境界値問題の解は、対応するSLAEの構築と解に還元されます。
区分線形関数
機能を設定するには 、グリッドのノードでその値を指定する必要があります。 座標を示します 番目のノード 、および関数の値 で 番目のノード-スルー 。
関数の値を見つけるには 任意の点で との三角形に属する 番目 そして 頂点、重心座標を導入します 0から1の値を取り、デカルト座標に関連付けられています 次の関係([3、セクション4.7.1]、[4、p。35]を参照):
ここから
どこで -記号の付いた三角形の領域。
関数の値は、式によって見つけることができます 。
数値積分
境界エッジ上の積分を そして セグメント上の積分に終わる :
ここに -リブの長さ 、
。
最後の積分を計算するには、ガウス求積式を適用します。
ポイント および重み係数 テーブルから取られた[3、秒。 5.9.2]。
三角形の積分を 番目 そして 三角形上の積分への頂点 :
ここに 三角形の面積です 、
。
最後の積分を計算するために、求積式[3、Sec。 5.11]。
ソフトウェア実装
一般的な考慮事項
このサブジェクト領域では、テストが難しい[10]ため、コードを非常に明確に記述することが重要です。 OOPを使用すると、コードを読みやすくすることができますOOPを使用するには、一連の概念を選択し、これらの用語でアルゴリズムを策定する必要があります。 これにより、まずアルゴリズムに注意を払い、次に実装の詳細にのみ注意を払うことができます。
三角測量
グリッドを構築するには、 FreeFem ++パッケージが使用され、三角測量は.mesh形式で保存されます。
ライブラリには、ファイルから読み取られるグリッドに関する情報を含むMesh
クラスが導入されています。
SLAUの構築
アルゴリズムを記述するために、基底関数と被積分関数(関数の積)のクラスが導入され、これらは基底クラスIntegrand
およびBoundaryIntegrand
から継承されます。 これらのクラスには、それぞれフィールドsupport
(media)およびboundary_support
(境界メディア)があります。 キャリアは、関数が0に等しくない三角形のリストです。境界キャリアは、関数が0に等しくない境界エッジのリストですValue
メソッドは、被積分関数のクラスに対しても定義され、特定のポイントで関数の値を計算します。
Integrate
およびBoundaryIntegrate
関数は、被積分関数を入力として受け取り、ホストリストを反復処理し、 Integrand
基本クラス( BoundaryIntegrand
)で定義された特定の三角形(または境界エッジ)で積分関数を呼び出し、仮想関数Value
を呼び出します。
したがって、SLAU構築コードの形式は次のとおりです。
for (int i = 0; i < data.N; ++i) { for (int j = 0; j < data.mesh.nodes_num; ++j) { for (auto s : data.mesh.adjacent_nodes[j]) { sys.AddCoeff(i, j, i, s, data.a[i] * Integrate(grad(phi[s]) * grad(phi[j])) + BoundaryIntegrate(data.b[i] * phi[s] * phi[j]) ); } for (int k = 0; k < data.N; ++k) { for (auto s : data.mesh.adjacent_nodes[j]) { sys.AddCoeff(i, j, k, s, Integrate(data.q[i][k] * phi[s] * phi[j]) ); } } sys.AddRhs(i, j, Integrate(data.g[i] * phi[j]) + BoundaryIntegrate(data.b[i] * data.w[i] * phi[j]) ); } }
SLAUソリューション
SLAEを解決するには、 MTL4ライブラリに実装されている反復法が使用されます。
結果へのアクセス
特定のポイントで解の値を見つけるには、このポイントを含む三角形を短時間で見つける必要があります。 これにはハッシュテーブルを使用できます。
領域を囲む長方形を破る に ブロックどこ 、 、 -囲む長方形の長さと幅、 -三角形分割三角形を囲む長方形の平均寸法。
それぞれの ブロックは、交差する三角形のリストを塗りつぶします。 これを行うには、すべての三角形をループして、それらを囲む長方形を見つけます。
交差するブロックを簡単に見つけることができます。
特定のポイントに対してクエリを実行すると、それが属するブロックを見つけ、このブロックに対応する三角形のリストを調べて、特定のポイントがどのブロックに属しているかを確認します。
テスト中
プログラムのテストは、既知の正確なソリューションを使用してタスクで実行されました。 ダブルメッシュリファインメントでは、誤差は約4倍または2倍減少します。これは、メソッドの精度が2次または1次であることを示しています。 1番目への収束の順序の減少は、関数の異なる値が与えられる境界部分の接合部での境界条件の不一致による可能性があります 。
おわりに
開発されたライブラリの大きなソルバーに対する利点は、そのシンプルさと、タスクの特定の機能(境界条件での区分的に一定の係数)を考慮できることです。 将来、3次元問題用の同様のライブラリを実装する予定です。このライブラリは、複雑な熱伝達のモデルで境界係数の最適制御の問題を解決するために使用されます。
ソース
- アレクシーエフG.V. 数理物理学の数値的方法。 有限要素法の紹介。 ウラジオストク:ダルナウカ、1999年。
- ダウトフR.Z.、カルチェフスキーM.M. 有限要素法の理論の紹介。 カザン:KSU、2004年。
- Zienkiewicz OC、Taylor RL、Zhu JZ有限要素法:その基礎と基礎。 エルゼビア、2005年。
- Segerlind L.有限要素法の適用。 M。:ミール、1979年。
- ポアソン方程式の例の有限要素法 // Habrahabr、07.27.2015。
- 180行未満のコードでFEM電卓を作成する //
Habrahabr、2015年12月1日。 - Freefem ++の使用方法 // Habrahabr、2013年6月6日。
- Gockenbach MS有限要素法の理解と実装。 SIAM、2006年。
- Smith IM、Griffiths DV、Margetts L.有限要素法のプログラミング。 ワイリー、2014年。
- 科学的なアプリケーションでユニットテストが機能しない理由 // Habrahabr、2010年4月26日。
- グレンキンG.V. 複雑な熱伝達モデルの境界最適制御問題を解決するためのアルゴリズム // Dalnevost。 仲間。 ジャーナル 2016.V. 16. No. 1. P. 24-38。