熱伝導解析の非線形反復の収束判定が、丸め誤差程度の揺れで成否が変わるほど厳しい

概要

熱伝導解析の非線形反復(heat_solve_main)の収束判定値は、線形ソルバの打ち切り誤差と同じくらい小さい。このため、丸め誤差程度の揺れで収束したりしなかったりする。並列計算では実行ごとに丸め誤差の範囲で解が変わるのは避けられないので、同じ入力でも反復上限に達して fstr_abort することがある。

非線形反復は、反復ごとに温度の全量を線形ソルバで解き直す。前回との差の2ノルム ||T_k - T_k-1|| が EPS(既定 1e-6)を下回ると収束とみなす。EPS は絶対値で、温度の大きさや節点数で正規化されていない(マニュアルの !HEAT には「収束判定値」としか書かれていない)。全量を解くので、毎回の解には反復法の打ち切り誤差が乗り、||ΔT|| はその大きさより小さくならない。

tests/analysis/heat/exR の R362(輻射、321節点)は ||T|| が約 5.2e3 なので、EPS 1e-6 は相対 2e-10 に当たり、CG の許容値(相対残差 1e-8)より厳しい。||ΔT|| が 1e-6 を下回るのは、連続する2回の CG が同じ反復回数で止まり、打ち切り誤差が打ち消し合ったときだけである。OpenMP を使うと、全体行列の加算順序が実行ごとに変わり、CG の反復回数が52回と53回で入れ替わる。そのため ||ΔT|| が 1.2〜1.7e-6 から下がらずに停滞する回が出る。exQ の Q362(熱伝達)も同じである。CI と同じイメージとバイナリで、2プロセス×2スレッドで20回ずつ解いた結果は次のとおり。

ケース 停滞せずに収束 停滞した回 最大の反復回数
exR R362 10 10 16
exQ Q362 9 11 18

1プロセス×1スレッドと2プロセス×1スレッドでは、結果が毎回同じで、このケースでは停滞しない。

CI では test_hybrid_analysis/heat/exR がこの理由で2回失敗した。2026-09-19 の ubuntu2204(job 16604828760)と、2026-10-02 の ubuntu2404(job 16907869819)で、どちらも R362 が20回で打ち切られた。テストは exR と exQ の EPS を 1e-3 に緩めて回避する(!680 (merged))。ただし、ユーザーのモデルでも、温度が高いほど、また節点が多いほど同じことが起きやすい。

増分形式(右辺を残差にして ΔT を解く)にすれば、線形ソルバの誤差が ΔT に比例して小さくなり、判定が丸め誤差に左右されなくなる。判定を ||ΔT||/||T|| の相対値にする方法もある。

Edited by inagaki