接触解析で線形ソルバの失敗を検出できていない問題を修正し、失敗理由を記録する (#814, #816)

Closes #814 (closed) #816 (closed)

概要

!589 (merged) が接触なし静解析に追加した検査を fstr_check_linear_solver に共通化し、Newtonドライバ4経路すべてに適用する。あわせて失敗理由を記録する。

commit 内容
hecmw: 接触elimination経路でソルバの判定結果を hecMAT に伝搬(前提となる修正)
static: 検査の共通化と失敗理由の記録(#814 (closed))
static: カットバック経路でMPC構造体を解放(#816 (closed))

接触経路に動作する検査が無かった理由

solve_LINEQ_contact_elim は istat = hecmw_mat_get_flag_diverged(hecMAT) を返すが、実際に解いているのは変換系 hecTKT で、フラグは hecMAT に届かない。istat は前回の解の値を読んでおり事実上常に0だった。つまり #814 (closed) が手本として引用している fstr_Newton_contactSLag の if( istat /= 0 ) も発火せず、接触経路には動作する検査が1つも無かった。

失敗理由 NRstat_i(knstDRESN)

従来は全て 4 (MatSolveError) に潰れていたものを3通りに分ける。既存コード1〜4の意味は変えない。

code message 条件
4 MatSolveError istat /= 0
5 MatNotConv 反復法かつ flag_converged == 0
6 MatDiverged flag_diverged /= 0

コード5を反復法に限定しているのは意図的。 直接法も相対残差が許容値を超えると同じフラグを立てないが、hecmw_solve はその場合警告のみで続行する(!stop がコメントアウト)。直接法は istat で判定する。

MPC構造体のリーク(#816 (closed))

hecmw_mpc_mat_init で確保した構造体が、カットバックの早期returnで hecmw_mpc_mat_finalize を経由せず漏れる。MPC_METHOD=3 では毎回1組ずつリークする。

修正中に同じ経路上で別の不具合を発見した。fstr_Quasi_Newton は入口で max_iter を100倍し末尾で戻すが、早期returnすると膨らんだ値が残る。次回呼び出しがそれを基準値として読むため、カットバックのたびに100倍ずつ累積する。これも併せて戻す。

挙動の変化

  • 接触解析が線形ソルバ失敗で実際にカットバックするようになる。 従来は検出できず、悪い解のまま次のNewton反復に進んでいた。狙い通りの修正だが、これまで何とか答えに辿り着いていた解析がカットバックに変わりうる
  • 接触なし静解析+直接法は !589 (merged) より緩くなる。 !589 (merged) はソルバ種別を問わず flag_converged を見ていたが、上記の理由で istat 判定に委ねた。テストでは露出しない
  • 接触ドライバの失敗経路でも knstCITER を記録するようにした(隣の収束失敗経路に合わせた)

レビュー時の注意

fstr_CheckConvergence.f90 の差分が大きいのは、このモジュールの記法をfistr1の他に揃えたため。fistr1全体で \param は97行・152ファイル中9ファイルのみ(!< は82ファイル)だが、うち24行をこのモジュールが占めていた。引数説明は !< へ、分岐固有の理由はその分岐の隣へ移し、引数リストを132桁で折り返した。コメント行97→45。当該hunkにロジック変更は無い。

Edited by inagaki

Merge request reports

Loading
Loading