接触探索で最近傍のマスタ面を採用する
Close #832 (closed)
概要
接触探索は、バケットから得たマスタ候補を先頭から走査し、射影判定を最初に通った候補で exit していました。候補の並び順は bucketDB_getCand が周囲 3×3×3 のバケットを k, j, i の順に走査して集めた順であって距離順ではないので、稜線や角の近くで複数のマスタ面が同時に判定を通る場合、どの面が選ばれるかがバケットの走査順という物理的に意味のない要因で決まっていました。選ばれる面が変われば法線が変わるため、接触力の向きも変わります。
候補集合を変えずに走査順だけを反転させる(do idm = 1,nCand を do idm = nCand,1,-1 にする)と、これがそのまま出ます。
| 条件 | 走査順を反転させたときに変わる結果ファイル |
|---|---|
| 基点(!604 (merged) の e6fd9239) | 12 / 12 |
| 本MR | 0 / 12 |
対象は tests/analysis/interaction/contact_smoothing の alag_nagata と slag_nagata です。基点では候補集合が同一でも走査順を変えるだけで全ての結果が変わり、本MRではバイナリ一致します。
「最近傍」は符号付き distance の最小ではなく |distance| の最小を採っています。distance は符号付きギャップ(正が隙間、負が貫入)で、根拠は fstr_contact_damping.f90 の contact_damping_weight が引数 g に signed distance (+ = gap, - = penetration) と明記していることです。符号付き最小を採ると最も深く貫入した候補を選ぶことになり、最近傍にはなりません。|distance| の最小は射影が直交射影なので節点から射影点までのユークリッド距離の最小、つまり最近点射影です。完全に同値の候補は対称なメッシュで起こりうるため、その場合はマスタ面の添字が小さい方を採り、選択が走査順に戻らないようにしています。
project_Point2Element は isin が真のとき cstate を書き換えるので、全候補を評価してから最良を採用するために試行用の tContactState に射影し、確定後に代入しています。これにより、棄却された候補が distance や干渉フィットの値をスレーブ状態に残していく副作用も無くなります。
track_contact_position も候補を先頭から走査していますが、直前の接触面を優先して隣接面をたどる意図的な処理なので変更していません。
接触相手が変わったのは slag_nagata の6節点で、接触ログで確認しました。いずれも2つのマスタ面がほぼ等距離にある稜線近傍の節点です。
| スレーブ節点 | 修正前のマスタ要素 | 修正後 |
|---|---|---|
| 101 | 59 | 139 |
| 102 | 139 | 145 |
| 113 / 125 / 137 / 149 | 65 | 144 |
今回は参照解の方を更新しています。
- 既存の参照解は、等価に成立する複数の答えのうち1つを、バケットの走査順という物理的に意味のない要因で選んだ結果です。バケットサイズ、領域分割、候補リストに触る変更のいずれでも再現できなくなります。
- 変わっているのは、ほぼ等距離にある2つのマスタ面のうちどちらに付くかで、最大差は NodalSTRESS の -6.34e-3(0.63%)です。
落ちるテストは contact_smoothing の1件だけで、serial・openmp・mpi・hybrid の4ラベルすべてで同じ1件でした。再生成後は全ラベル全件 PASS します。
変更内容
| commit | 変更内容 |
|---|---|
| 52f5cb5a contact: pick the nearest master surface instead of the first match | scan_contact_state と scan_embed_state の CONTACTFREE 分岐で、候補を全て試行用の状態に射影し最近傍を採用 |
| 3d591d66 tests: regenerate the contact smoothing references | contact_smoothing の参照解6件を再生成 |