サロゲートモデルを作成してみました。その覚書です。
コードのほとんどはライブラリと生成AIによるものです。
目的
FEMの解析結果からサロゲートモデルを作成して、任意の条件による結果を推論させます。
簡単な片持ち梁の引張りで行いました。簡単のために、変位とミーゼス応力だけを対象にしています。
概要
FreeCADで作成した10x10x100mmの片持ち梁の引張りに対して行いました。
処理構成
コードは以下の処理を行っていきます。
・教師データの読み込み
・学習
・推論
コード
とりあず、実行だけするようにしたコードです。
google colabで動きます。
main(初期版)
このノートブックは、有限要素法(FEM)の解析結果を学習し、高速に予測するための「サロゲートモデル(代理モデル)」を作成・検証するコードです。
具体的には、3次元の形状・境界条件・荷重条件を入力とし、変位($u_x, u_y, u_z$)とフォン・ミーゼス応力の分布を出力するAIモデル(Fourier Neural Operator)を構築しています。
処理の流れに沿って、各パートの役割を解説します。
1. 環境構築とデータ準備
(セル 1-2)
- 目的: 必要なライブラリのインストールと、学習データのダウンロード・解凍です。
- 内容:
- Google Colabとローカル環境の両方に対応できるようにフラグ(
USE_COLAB)で分岐しています。PyVista(3Dメッシュ処理用)やTorch(AI学習用)などを準備します。- GitHubからFEM解析結果(
.vtuファイル群)を含むZIPファイルをダウンロードし、展開しています。2. 設定とデータ前処理(重要)
(セル 3-5)
ここがこのコードの肝となる部分です。FEMのデータをAIが扱いやすい形に変換しています。
- Configクラス:
nx, ny, nz = 24, 24, 24: 解析空間を24×24×24の**3次元グリッド(ボクセル)**に分割しています。scales: 変位や応力の値が非常に小さい/大きいため、学習しやすい数値範囲に正規化するための係数を設定しています。- データ読み込み (
load_case):
.vtuファイルから、節点座標・変位・応力データを抽出します。- ボクセル化 (
interpolate_to_grid_3d_optimized):
- FEMのメッシュ(非構造格子)はそのままでは畳み込みなどが難しいため、
NearestNDInterpolatorを使って**規則正しい3次元グリッドデータに変換(補間)**しています。- 入出力データの作成 (
make_inp_out):
- 入力 (4チャンネル): [形状マスク, 固定条件マスク, 荷重位置マスク, 荷重値]
- 出力 (4チャンネル): [変位x, 変位y, 変位z, ミーゼス応力]
3. データセットの作成
(セル 6-7)
- 内容:
- フォルダ内の全
.vtuファイルを読み込み、ファイル名(例:1_-1000)から荷重値(-1000Nなど)をパースして正解ラベルと紐付けています。- PyTorchの
TensorDatasetとDataLoaderを作成し、学習の準備を整えます。- Pandasを使ってデータの統計量(最大応力など)を表形式で確認しています。
4. モデル定義:3D FNO (Fourier Neural Operator)
(セル 8)
- 採用モデル: Fourier Neural Operator (FNO)
- 特徴:
- 通常のCNN(畳み込みニューラルネット)ではなく、**周波数領域(FFT: 高速フーリエ変換)**で特徴抽出を行うモデルです。
- 物理現象(偏微分方程式など)の学習において、従来のCNNよりも大局的な特徴(全体の変形挙動など)を捉えるのが得意で、解像度に依存しない学習が可能です。
SpectralConv3d: 3次元空間でのフーリエ変換処理層を定義しています。5. 学習 (Training)
(セル 9)
- 内容:
- 作成した3D FNOモデルを学習させます。
- 損失関数(Loss)は
MSELoss(平均二乗誤差)を使用し、予測値とFEM正解値のズレを最小化します。- エポック数50で、Lossが
1.79→0.002まで下がっており、正常に学習が進んでいることがわかります。6. 推論と可視化
(セル 10)
- 目的: 学習済みモデルを使って、任意の荷重条件での結果を予測します。
- 内容:
- 学習データにはない(かもしれない)任意の荷重(例: 2000N)を入力として作成します。
- モデルに投入し、瞬時に変位・応力分布を予測させます。
- 予測結果の正規化を解除し、物理単位(m, Pa)に戻します。
- Matplotlibによる可視化: 3次元データの中央断面(X-Z平面)をスライスし、カラーマップで表示しています。これにより、荷重によって部材がどう変形し、どこに応力が集中するかを視覚的に確認できます。
技術的なまとめ
このコードは、**「FEMの計算コスト削減」**を目指す典型的なAI活用事例です。
- 計算の高速化: 一度学習すれば、FEMで数分〜数時間かかる計算を、AI(GPU)ならミリ秒単位で推論できます。
- ボクセル変換: 複雑なメッシュデータを3D画像のように扱うことで、強力な画像処理系AI技術(FNOや3D-CNN)を適用可能にしています。
- FNOの採用: 物理シミュレーションのサロゲートモデルとして現在最も注目されているアーキテクチャの一つを採用しており、汎化性能(学習していない条件への適応力)が期待できる構成です。
結果評価
推論結果は「非常に妥当」であると判断できます。
学習データの統計情報と推論結果を比較・検証した根拠は以下の通りです。
1. 定量的な比較(正解値 vs 推論値)
Notebook内のセル[26](データサマリ)とセル[29](推論結果)を比較すると、オーダー(桁数)および数値が非常に高い精度で一致しています。
項目 学習データの正解値 (2000N時) 推論結果 (2000N指定) 誤差・評価 最大ミーゼス応力 約 20.0 MPa (20,000,900 Pa) 20.5 MPa (20,519,000 Pa) 誤差約 +2.5%
非常に良好な精度です。最大変位 ($U_z$) 約 $0.95 \times 10^{-5}$ m $1.04 \times 10^{-5}$ m 誤差約 +9.0%
グリッド近似の影響を含めると許容範囲です。
- 参照元:
- 正解値: 出力ログ の
2_2000行目- 推論値: 出力ログ の
Ux (荷重点)...部分2. 物理的な挙動の整合性
出力された変位成分($U_x, U_y, U_z$)の関係性を見ても、物理的に自然な挙動を示しています。
- 主な変形方向: 荷重方向である $U_z$ の変位量($10^{-5}$オーダー)が最も大きく、$U_x, U_y$($10^{-7} \sim 10^{-6}$オーダー)はそれに比べて小さい値です。これはZ軸方向に引っ張られた(または押された)際のポアソン効果による横変形として妥当な比率です。
- 応力分布: ヒートマップ(セル[29]の図示部分)において、ノイズ(ランダムな点)が少なく、連続的な分布が保たれています。これはFNO(Fourier Neural Operator)が空間的な連続性を正しく学習できている証拠です。
3. 学習の収束状況
セル[28]の学習ログを確認すると、Lossの推移が健全です。
- 開始時: 2.42
- 終了時: 0.0016
- 評価: Lossが滑らかに減少しており、モデルがデータセットのパターンを十分に学習できたことを示しています。
結論と次のステップ
現状の結果は、サロゲートモデルとして十分に機能していると言えます。特に応力値の誤差が2.5%程度というのは、初期検討としては非常に優秀な結果です。
さらに検証精度を高めるための提案:
- 未知の荷重でのテスト:今回は学習データに含まれていると思われる
2000Nで推論していますが、学習データに存在しない「2500N」や「5500N」などの条件で推論を行い、線形補間(または非線形な挙動)が正しく行われているか確認することをお勧めします。- グリッド解像度の検討:現在は
24x24x24ですが、もし形状の細かい特徴(R部分など)を捉える必要がある場合は、解像度を上げる(例: 32x32x32)ことで、変位の誤差(現在9%)がさらに改善する可能性があります。現状のままでも、2000N荷重時の挙動を即座に予測するサロゲートモデルとして成功しています。
操作
ローカルで実行する場合とcolab上で実行する場合には、条件が違うので、フラグで切り替えます。

ローカル実行の場合には教師データvtuがフォルダvtu内に置かれていることが前提で、colabはgithub上からダウンロードして現在のセッション内に展開するようにしています。
また、ライブラリですが、ローカルは作業環境にすでにインストールされているものとしています。colabはインストールするようにしています。
出力
ノートブック上の表示

vtuファイル


注記
実施する上でひっかかったことなど
引張りと圧縮
軸方向の引張りの解析ですが、サンプルだと引張りの条件だけで学習しています。
そのため、圧縮の荷重については、学習がされていないことになります。
推論にマイナス荷重(-2000Nなど)を対象としても、妥当な結果とはなりません。
(応力は絶対値で評価する場合には合います)
引張りと圧縮を精度よく推論できるようにするには、どちらも十分なデータ数が必要になります。(または、工学的な関係性を考慮した出力の変換)
学習データ
推論による結果は、学習データに左右されます。簡単な引張りのモデルですが、詳細にみると境界条件の固定方法による歪みが影響します。(本モデルでは軸回転が入っている)
教師データ
以下の教師データを入力荷重を変えて作成しました。実際に用いたデータは引張りのデータ(3以降の奇数番)です。
数が少ないため、引張りと圧縮の両方で学習しても精度がでませんでした。プラスとマイナスなので、反転するのはデータ数が大量に必要なようです。
(青文字の項目は最大最小のどちらを見ているか)
| No | 荷重値 | ファイル名 | 変位 | 変位x | 変位y | 変位z | 変位mag | ミーゼス応力 |
|---|---|---|---|---|---|---|---|---|
| 1 | 1000N | 1_1000 | 最大 | 2.2 µm | 0.0 mm | 4.8 µm | 5.7 µm | 10.0 MPa |
| 2 | -1000N | 1_-1000 | 最小 | -2.2 µm | 0.0 mm | -4.8 µm | 5.7 µm | 9999.6 kPa |
| 3 | 2000N | 2_2000 | 最大 | 4.6 µm | 0.0 mm | 9.5 µm | 11.6 µm | 20.0 MPa |
| 4 | -2000N | 2_-2000 | 最小 | -4.6 µm | 0.0 mm | -9.5 µm | 11.6 µm | 20.0 MPa |
| 5 | 3000N | 3_3000 | 最大 | 7.4 µm | 0.0 mm | 14.3 µm | 17.7 µm | 30.0 MPa |
| 6 | -3000N | 3_-3000 | 最小 | -7.4 µm | 0.0 mm | -14.3 µm | 17.7 µm | 30.0 MPa |
| 7 | 4000N | 4_4000 | 最大 | 9.6 µm | 0.0 mm | 19.0 µm | 23.4 µm | 40.0 MPa |
| 8 | -4000N | 4_-4000 | 最小 | -9.6 µm | 0.0 mm | -19.1 µm | 23.4 µm | 40.0 MPa |
| 9 | 5000N | 5_5000 | 最大 | 11.5 µm | 0.0 mm | 23.8 µm | 28.9 µm | 50.0 MPa |
| 10 | -5000N | 5_-5000 | 最小 | -11.5 µm | 0.0 mm | -23.8 µm | 28.9 µm | 50.0 MPa |
| 11 | 6000N | 6_6000 | 最大 | 14.8 µm | 0.0 mm | 28.6 µm | 35.4 µm | 60.0 MPa |
| 12 | -6000N | 6_-6000 | 最小 | -14.8 µm | 0.0 mm | -28.6 µm | 35.4 µm | 60.0 MPa |
| 13 | 7000N | 7_7000 | 最大 | 16.5 µm | 0.0 mm | 33.3 µm | 40.7 µm | 70.0 MPa |
FreeCADでCalculixで解析実行させると、frdフォーマットの結果が作成されます。
結果ファイルをvtu形式にして保存します。他のフォーマットでも、Pythonで変換なりすればいいと思います。vtuは、ParaViewなどの外部ソフト読み込める形式なので、確認などもそちらで行えます。



コメント