可視化出力の MATERIAL_ID / ORIENTATION が !EQUATION の多いモデルで配列外参照して落ちる
現象
!EQUATION の本数が !SECTION の本数より多いモデルで、!OUTPUT_VIS に MATERIAL_ID,ON または ORIENTATION,ON を指定すると、step 0 の可視化出力を書く時点(fstr_setup: OK の直後)で配列外参照が起きる。
MATERIAL_ID,ON: 通常ビルドでは止まらないことが多いが、可視化ファイルのMATERIAL_IDに!SECTIONの本数を超える値や負の巨大値が書かれる。環境によってはアクセス違反で無言終了する(Windows で確認)。ORIENTATION,ON: Linux の通常ビルドでもfstr_setup: OKの直後に segfault する。
再現手順
in-tree のテスト tests/analysis/static/mpc_pena_iter(!EQUATION 12 本 / !SECTION 1 本)だけで再現する。
cp -r tests/analysis/static/mpc_pena_iter /tmp/mpcrepro && cd /tmp/mpcrepro
sed -i 's/^!VISUAL, method=PSR/!OUTPUT_VIS\n MATERIAL_ID,ON\n!VISUAL, method=PSR/' test.cnt
cat > hecmw_ctrl.dat <<'EOT'
!MESH, NAME=fstrMSH, TYPE=HECMW-ENTIRE
test.msh
!CONTROL, NAME=fstrCNT
test.cnt
!RESULT, NAME=fstrRES, IO=OUT
test.res
!RESULT, NAME=vis_out, IO=OUT
test_vis
EOT
fistr1 -t 1-fcheck=bounds つきでビルドした fistr1 では次で停止する。
At line 1267 of file .../fistr1/src/analysis/static/make_result.f90
Fortran runtime error: Index '4' of dimension 1 of array
'hecmesh%section%sect_mat_id_item' above upper bound of 1ORIENTATION 側は上に加えて test.cnt の !SECTION, SECNUM=1, FORM361=FI を
!ORIENTATION, NAME=ORI1
1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0
!SECTION, SECNUM=1, ORIENTATION=ORI1, FORM361=FIに置き換えて !OUTPUT_VIS に ORIENTATION,ON を足すと、通常ビルドでも segfault する。
原因
HEC-MW は !EQUATION 1 本につき 1 個の疑似要素(3 次元では要素タイプ 912)を生成し、その hecMESH%section_ID に !SECTION の番号ではなく MPC の通し番号 1..n_mpc を入れる(hecmw1/src/common/hecmw_io_mesh.c の setup_mpc_sectid)。S2S 接触の !CONTACT_PAIR から生成する patch 要素(1031 等)も同様に接触ペアの通し番号を持つ(setup_contact_sectid)。
fistr1/src/analysis/static/make_result.f90 の MATERIAL_ID 出力(:1266-1267)と ORIENTATION 出力(:1648-1649)は全要素を回り、この section_ID をそのまま sect_mat_ID_item / sect_orien_ID(長さ = !SECTION の本数)の添字に使うため、通し番号が !SECTION の本数を超える疑似要素で配列の外を読む。ORIENTATION は拾った値をさらに g_LocalCoordSys(cdsys_ID) の添字に使うので segfault になる。
同じ出力を持つ fistr1/src/analysis/precheck/precheck_make_result.f90(:136, :262)は if(isect >= 1 .and. isect <= hecMESH%section%n_sect) で既に guard されている。
期待する動作
疑似要素では !SECTION の配列を引かず、MATERIAL_ID は 0、ORIENTATION は配向なし(cdsys_ID = -1 相当)として出力する。実要素の出力は変えない。
precheck 側と同じ範囲チェックを make_result.f90 の 2 箇所に入れる修正を用意しているので、この issue に紐づけて MR を出す。
補足
- 同じ形の無 guard 参照が
fistr1/src/analysis/heat/heat_echo.f90:131-132(熱伝導 +!ECHO、未実測)にも残っている。 !CONTACT_PAIRの本数 >!SECTIONの本数でも同じ条件になるはずだが未実測。