解析制御ファイルの名前を読み込み時に大文字化する
Close #828 (closed) Close #840 (closed)
概要
名前の大文字化がmshリーダ側だけで行われていた。hecmw_io_hec.c は集合名・材料名・振幅名・接触ペア名を 読み込み時に HECMW_toupper で大文字化するが、cntリーダ側の fstr_ctrl_util.c にある Strupr は #if 0 で 無効化されており、cntの値は原文のまま保持されていた。
この非対称を、名前を比較する箇所ごとに hecmw_streqr または fstr_strupr で個別に吸収していたため、 どちらかを呼び忘れた箇所で小文字の名前が解決できない。本MR時点で以下が残っていた。
| 箇所 | 小文字で書いたときの挙動 |
|---|---|
| !OUTPUT_RES / !OUTPUT_VIS の GROUP= | 節点群が解決されず既定の出力範囲になる |
| !STEP / !ISTEP のデータ行の項目名 | その境界条件・荷重・接触がステップに登録されない |
| !OUTPUT_RES / !OUTPUT_VIS のデータ行の項目名 | その出力項目が結果ファイルに出ない |
とくに !STEP のデータ行が効かない場合、解析はエラーを出さずに完走し、境界条件が一つも適用されない 自明解を出す。
修正
cntリーダのC層で、文字列書式 'S' で読んだ値を大文字化することにした。正規化の入口が1箇所になるため、 今後キーワードやパラメータを追加する際に大文字化を呼び忘れる余地がない。これは入力規則が既に 「名前は大文字小文字を区別せず、内部的にはすべて大文字として扱われる」と規定している動作である。
大小を保存する必要があるファイル名は、新設した書式 'F'('S' から大文字化を除いたもの)で読む。 'S' で読んでいる値を全数監査した結果は次のとおりで、名前でもファイル名でもない値は無かった。
| 経路 | 名前 | ファイル名 |
|---|---|---|
| パラメータ値 | 36 | 5 |
| データ行・データ配列の 'S' 項目 | 34 | 1 |
既定を大文字化する側に置いたのは、失敗の向きを変えるためである。名前が多数・ファイル名が少数で
あるため、名前を読むパラメータを追加する開発者は何もしなくても正しく動く。残る書き忘れは
「ファイル名なのに 'F' を書かなかった」場合だけで、その症状は指定したファイルが開けないという
即座に分かるエラーであり、黙って誤った結果を出すことがない。実際に !INCLUDE の書式を 'S' に戻すと
### Error: Cannot open FSTR control file : SOLVER_LOWER.CNT で停止することを確認した。
リーダが大文字化するようになったため、読んだ直後に大文字化していた fstr_strupr(実装1・呼び出し6)と pc_strupr(実装4・呼び出し4)を削除した。pc_strupr は判定が a > iachar('Z') であり、英小文字だけでなく 0x5B〜0x60 と 0x7B〜0x7E の記号も変換していたが、実引数は BX, GRAV, CENT, S1, BF 等の荷重種別だけなので 結果は変わらない。
hecmw_streqr による比較21箇所はそのまま残した。双方が大文字化されていれば結果は変わらず、 メッシュ側の名前がリファイナやパーティショナなど別経路で入ってきた場合の保険になる。
既存テストは serial 105件・hybrid 98件すべてPASSする。
変更内容
| コミット | 要約 |
|---|---|
| aa0837b0 Uppercase the names of the control file as they are read | C層で 'S' の値を大文字化し、ファイル名用の書式 'F' を新設。ファイル名6箇所を 'F' に変更 |
| 23dd1252 Remove the uppercasing from the callers of the control file reader | 冗長になった fstr_strupr と pc_strupr を削除 |
| 4dd43dff Add a test for lower case names in the control file | mshが大文字で定義した名前をcntが小文字で参照する回帰テストを追加 |
'F' で読むのは !ULOAD の FILE、!WRITE の FILE と FILENAME、!INCLUDE の INPUT、!EIGENREAD のログ ファイル名の6箇所である。最後の1つはパラメータではなくデータ行の書式で読んでいるため、'F' は パラメータ値とデータ行の両方で使える。