Loading
線形静解析の熱荷重がsubstepごとに過大になる不具合の修正
線形静解析の熱荷重がsubstepごとに過大になる不具合の修正
Issue #908 (closed) に対するMRです。
線形静解析(!SOLUTION, TYPE=STATIC)で弾性材料に熱荷重をかけ、!VERSION 5 で !STEP, SUBSTEPS を2以上にすると、substepが進むにつれて変位・応力が累積的に過大になる。10 substepでは最終変位が正解の約4.6倍になる。計算はエラーなく正常終了するため、利用者は誤りに気づきにくい。
不具合の内容
線形解析(INFINITESIMAL)の応力更新は増分形 σ = σ_bak + D (dstrain − strain_bak) である。弾性材料では、dstrain が初期温度基準の全熱ひずみを差し引いた機械ひずみであるのに対し、strain_bak は熱ひずみを含む全ひずみである。そのためsubstepごとに、前substepまでの熱ひずみに相当する応力が余分に差し引かれる。
期待される動作と現状
- 期待される動作:線形解析では荷重係数が時間に比例するので、substep n の変位は1step解の n/10 倍になり、最終substepの結果は
SUBSTEPS=1の解と一致する。 - 現状:最大変位の比(対 1step解)が次のとおり累積的に大きくなる。
| substep | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|---|---|---|---|---|---|---|---|---|---|---|
| 修正前 | 0.100 | 0.200 | 0.400 | 0.700 | 1.100 | 1.600 | 2.200 | 2.900 | 3.701 | 4.601 |
| 期待値 | 0.1 | 0.2 | 0.3 | 0.4 | 0.5 | 0.6 | 0.7 | 0.8 | 0.9 | 1.0 |
不具合の再現方法
- 使用バイナリ:origin/master( 007551a0)をクリーンビルドしたもの(
bin_base/fistr1)。ビルド環境はenv_build.sh、構成ログはout_cmake.log、ビルドログはout_build_base.log。 - 入力:ユーザー提供の
/data/a/a878/frontistr/calc/test_thermalstress/の2ケースを作業フォルダにコピーした。run_base_exF_before_1step/:SUBSTEPS=1(参照解)run_base_exF_before_1step_version5/:!VERSION 5、SUBSTEPS=10run_base_substep10_noversion/:上記から!VERSION行のみを削除したもの- 共通条件:361要素、弾性(E=4000, ν=0.3)、
!REFTEMP 20、初期温度20℃、!TEMPERATURE120℃、!BOUNDARYFIX 1-3
- 実行:各ディレクトリで
OMP_NUM_THREADS=4 ../bin_base/fistr1。比較はpython3 compare_steps.py <参照> <対象>で行った。 - 結果:
run_base_exF_before_1step_version5:上表のとおり再現した。最終substepの参照解との最大相対差は DISPLACEMENT 3.60、NodalSTRESS 5.15。run_base_substep10_noversion:!VERSIONなし(VERSION 3 相当)では、線形静解析の!STEP, SUBSTEPSが無視され、1 substepで終了する。結果は参照解と完全に一致した。つまり本不具合は、!VERSION 5でsubstep分割が有効になったときに顕在化する。
不具合修正の試行
原因に対する仮説
- 応力更新での熱ひずみの扱いが不整合(主因)
fstr_UpdateNewton(fistr1/src/analysis/static/fstr_Update.f90:137-146)では、基準温度tt0を材料で切り替えている。- 弾塑性/NORTON材料:前substep温度
last_temp→ 熱ひずみは増分 - それ以外(弾性など):初期温度 → 熱ひずみは全量
- 弾塑性/NORTON材料:前substep温度
Update_C3等(fistr1/src/lib/static_LIB_3d.f90ほか)では、dstrain = ε(u) − EPSTH(tt0→ttc)を作る一方で、gauss%strain = dstrain + EPSTH(全ひずみ)を保存し、fstr_UpdateStateがこれをstrain_bakにコピーする。Update_Stress3Dの INFINITESIMAL 分岐ではσ = σ_bak + D (dstrain − strain_bak)となり、弾性材料では Δε − εth_{n+1} が使われる(正しくは Δε − (εth_{n+1} − εth_n))。- その結果、内力が過小になって次substepの右辺が過大になる。線形解析はNewton反復1回で打ち切る(
fstr_solve_NonLinear.f90:166)ため、誤差は補正されずに累積する。 - 1次元モデル
u_{n+1} = u_n − σ_n + a、σ_{n+1} = σ_n + (u_{n+1} − (n+1)a − u_n)で計算した比は 0.1, 0.2, 0.4, 0.7, 1.1, …, 4.6 となり、実測と完全に一致した。 - 解決策として、次の2案を比較した。
- 案A:線形時に
tt0 = last_tempとする(fstr_Update.f90)。この案では、全量形で応力を計算する2D要素(UPDATE_C2、static_LIB_2d.f90:509)・UP要素(StressUpdate_up)・粘弾性を除外する条件分岐が必要になる。 - 案B:
Update_Stress3Dの INFINITESIMAL 分岐で、前状態の熱ひずみ εth_n = EPSTH(tt0→ttn) を戻して機械ひずみ増分を作る。 - 案Bは、影響範囲がこのルーチンを呼ぶ増分形の3D要素(C3/Bbar/IC/Fbar/SESNS)に限られる。弾塑性材料では
tt0 = ttnなので εth_n = 0 となり、挙動は変わらない。ユーザーと協議のうえ、案Bを採用した。
- 案A:線形時に
仮説1の検証
- 修正内容:
Update_Stress3Dの INFINITESIMAL 分岐で、ttn ≠ tt0のときCal_Thermal_expansion_C3(tt0, ttn, …)によりEPSTHNを求める。これを用いて機械ひずみ増分dmstrain = dstrain − strain_bak + EPSTHNを作り、応力増分とひずみエネルギーの計算に使う。異方性の判定はUpdate_C3と同様にMC_ORTHOEXPの有無で行う。 - 結果(
run_fix_exF_before_1step_version5/、バイナリbin_fix/fistr1):比が 0.100, 0.200, 0.300, …, 1.000 となり、累積は解消した。最終substepの参照解との最大相対差は DISPLACEMENT 1.66e-4、NodalSTRESS 3.98e-4、NodalMISES 1.58e-4 である。 - SUBSTEPS=1 のケース(
run_fix_exF_before_1step/)は修正前と完全に一致し、影響はない。
テスト結果
- 解析実行ディレクトリ:
run_fix_exF_before_1step_version5/:不具合ケース。可視化出力は BIN_VTK でvis_out/にある。run_fix_exF_before_1step/:SUBSTEPS=1 ケース。- 結果は「仮説1の検証」のとおりである。pvbatch がない環境のため、画像による確認は省略した。
- serialテスト(
ctest --test-dir FrontISTR/build -L ',serial$'、ログout_ctest_serial.log):112件中111件がPASSした。test_serial_solver/saamgのみ FAIL した。A361/A761/A641_mpc で SA-AMG が収束しない(indefinite preconditioner / 反復上限)。- 修正前のバイナリ(
bin_base/fistr1)で同じテストを実行しても、同じ3メッシュで同様に失敗した(out_test_saamg_base.log)。したがって本修正とは無関係の既存事象である。 - 熱荷重テスト
analysis/static/exFと、要素ライブラリのテスト(3dIC, Bbar, Fbar, selectiveESNS, UP)、材料テスト(Elastoplastic, Viscoelastic など)はすべてPASSした。
test計算の可視化結果を添付します熱応力解析.pdf