領域分割時に節点応力・ひずみをハロー交換する (領域境界の NodalMISES/主応力が逐次実行と一致しない)
close #819 (closed)
概要
領域分割 (DD) 実行時、領域境界の節点応力・ひずみ (およびそれを読む NodalMISES・主応力) が
逐次実行と一致しません。fstr_NodalStress3D の節点平均の後にハロー交換が無く、外点
(ghost) スロットに不完全な平均値が残るためです。5 行の追加で修正します。
ソルバの解 (変位・反力・接触力) は変わらず、影響は出力・後処理のみです。
現象
np=2 (KMETIS, DEPTH=1) の 3 次元ソリッド静解析で、ランクごとの .res を逐次実行と
比較すると、内点 (owner) は解の精度どおり一致するのに、外点 (ghost) の NodalMISES だけが
数 % ずれます (下記の実測では場のスケール比 3.9%、節点単位で最大 9.1%)。
可視化でもランクごとに piece を書く形式 (VTK / BIN_VTK の .pvtu) では外点の値が
そのまま入るため、領域境界に沿った縞として見えます。
一方、rmerge で結合した .res は owner スロットしか拾わないので、この不一致は結合結果には
現れません。同様に、結合してから書く可視化形式 (COMPLETE_AVS 等) にも現れません。
既存の MPI テストが結合結果 (rmerge) で比較しているため、これまで検出されていませんでした。
機構
fstr_NodalStress3D は各領域が保持する全要素 (内部要素 + オーバーラップ要素) の寄与を
節点へ足し込み、寄与要素数 nnumber で平均します。内点は要素 star が領域内で完結するので、
この平均は逐次実行と同じ値になります。一方、外点は要素 star が切れているため、少ない
要素数で平均された値が残ります。その後にハロー交換が無いので、この不完全な値がそのまま
.res と可視化へ流れます。get_mises と make_principal は同じ配列を読むので、
NodalMISES と主応力も外点で同じだけ狂います。
修正
節点平均 (と SESNS 平滑化) の直後に、hecmw_update_R で owner の値を外点へ複製します。
fstrSOLID%STRESS/STRAIN は SOLID%STRESS/STRAIN と同じ実体を指すので make_principal
も同時に整合します。tnstrain は条件付きでしか associate されないため associated() で
保護します。hecmw_update_R は import (外点) スロットのみを書き、隣接領域が無い場合
(逐次実行) は即 return するため、owner の値と逐次実行の出力は変わりません。
検証
本コミットの有無だけが異なる 2 つのバイナリ (同一ビルドツリー、当該 1 ファイルのみ差し替え) で比較しました。
- 逐次実行は不変:
tests/analysis/static/exA/A361と 2 ブロック接触モデルの.resが 修正前後でバイト一致 - DD で外点誤差が消える (np=2、ランクごとの
.resを逐次実行と突合):exA/A361(接触なし・6 面体): 外点 NodalMISES の最大誤差 2.25 → 3.0e-9。 内点の誤差 3.2e-9 に対する比が 7.1e8 → 0.96 (= 内点と同水準)- 2 ブロック接触モデル (節点-面, ALAGRANGE): 同 0.36 → 5.8e-6 (比 6.0e4 → 0.96)
- 変化するのは外点のみ: ランクごとの
.resの owner スロットは修正前後で全てバイト一致 - 可視化 (piece 形式):
exA/A361をoutput_type=VTK(ランクごとの.pvtu) で出力すると、 修正前は piece 内の 21 節点が逐次実行と 1e-4 超のずれ (最大 2.25)、修正後は 0 節点 (残差 6e-6 = Float32 出力の丸め)。結合形式 (COMPLETE_AVS) は修正前後でバイト一致 - 既存の参照結果の再生成は不要:
rmergeで結合した.resは修正前後でバイト一致 ctestのanalysisサブセット: serial 63/63 pass、mpi 63/63 pass
対象範囲
3 次元ソリッド (flag33 == 0) の節点応力・ひずみ、およびそれを読む NodalMISES・主応力です。
2 次元・シェル (6 自由度/33) の層別配列は本 MR の範囲外です (今後の対応)。