CFDデータのデータマネジメント — MLOpsとAI Readyの視点から
はじめに
1回のCFD解析であれば、ケースディレクトリを1つ作って結果を眺めれば済みます。 ところが最適化ループを回したり、サロゲートモデルの学習データを作ったりすると、扱うケースは数百から数万に膨れ上がります。 このスケールになって初めて、「あのケースの境界条件は何だったか」「どのメッシュ生成ロジックで作った形状か」「学習に使っていいデータはどれか」といった問いに、ファイル置き場を目で追うだけでは答えられなくなります。
この記事では、CFDデータを機械学習で使える状態に整えるAI Readyという観点と、それを一度きりでなく継続的に回す仕組みであるMLOpsという観点の2軸で、CFDデータのデータマネジメントを整理します。
CFDデータが厄介な理由
CFDデータの管理が難しいのは、単に容量が大きいからだけではありません。
- 形式が多様: メッシュ、時系列のフィールドデータ、スカラー値(抗力係数など)、残差履歴が、それぞれ別のファイルとして生成される
- ソルバー依存: OpenFOAMのケースディレクトリ、Fluentの
.cas/.dat、CGNSなど、フォーマットも粒度もソルバーごとに異なる - 結果だけでは再現できない: 境界条件・メッシュ生成パラメータ・ソルバー設定・収束判定基準は、結果ファイルの外側(ジョブスクリプト、実行者の記憶、Excelの管理表など)に散らばりがちで、結果ファイルだけを見ても「どう作られたか」が追えない
1件だけの解析ならこの散らばりは実害になりません。 しかし同じ条件で大量に回す最適化やサロゲート学習の場面では、この散らばりがそのままデータの信頼性の欠如として跳ね返ってきます。
AI Ready — 学習データとして使える状態とは
生のCFD出力(VTKやfoam形式のフィールドデータ)は、そのままでは学習に使えません。 サロゲートモデルのアーキテクチャを選ぶで整理した、テーブル・規則格子・点群・メッシュという入力の型のどれかに、後処理の段階で変換しておく必要があります。 つまりAI Readyとは、生データを「どのアーキテクチャにも渡せる、構造の揃ったデータ」にしておくことだと言い換えられます。
これを支えるのが、ケース単位のメタデータのスキーマ化です。 設計変数・境界条件・メッシュ品質・収束ステータス・目的関数値といった項目を固定のスキーマとして決め、すべてのケースで同じ形式で残します。
| 項目 | 内容 | 用途 |
|---|---|---|
case_id | ケースを一意に識別するID | 設計変数・メッシュ・結果を紐付けるキー |
design_vars | 形状パラメータ、境界条件などの入力 | 学習データの入力特徴量 |
mesh_quality | 要素数、y+、非直交度など | 品質ゲートでの足切り判定 |
convergence | 残差履歴、収束フラグ | 未収束ケースの除外 |
objective | 抗力係数など目的関数値 | 学習データの出力(教師信号) |
status | success / diverged / mesh_error など | データセットに含めるかの判定 |
このスキーマがあることで、「設計変数→メッシュ→解析条件→結果」という一連の生成過程をcase_id一本で追跡できるようになります。
逆にこれがないと、学習データセットの1行がどう生成されたのか後から誰も説明できない、という状態に陥りがちです。
品質ゲートも同じスキーマの上に乗ります。 発散ケース、未収束ケース、メッシュ品質が基準を満たさないケースを機械的に判定し、学習データセットに混入させない仕組みを、後処理パイプラインの中に組み込んでおきます。 人手でチェックする運用は、件数が数百を超えたあたりから確実に破綻するため、具体的な基準は次節で整理します。
品質ゲートの設計 — 何を、どんな基準で見るか
品質ゲートは、性質の異なる2種類のチェックの組み合わせです。 「メッシュが正しく切れているか」というメッシュ品質と、「解析が正しく収束しているか」という収束品質を、それぞれ見ておきます。
メッシュ品質
メッシュ生成の段階で壊れているケースは、ソルバーを回す前に弾いておくのが最も安上がりです。
- 負体積セル(negative volume cells): セルの頂点順序が崩れ、体積が負に計算されてしまうセル。1つでも存在すればメッシュ生成そのものが破綻しており、そのまま解析に進めても発散するか誤った結果を返すだけなので、即座に除外します
- スキューネス(skewness): セルが理想形状からどれだけ歪んでいるかを表す指標。極端に歪んだセルは数値誤差や発散の原因になるため、最大値や基準を超えるセルの割合に閾値を設けます
収束品質
メッシュが健全でも、解析自体が収束していなければ結果は使えません。
- 残差(residuals): 連続の式・運動量式などの残差が、あらかじめ決めた閾値(例: )を下回っているかを見ます。ただし乱流・非定常解析では残差が下げ止まったまま実質的には収束していないことも多く、残差だけでは判定材料として不十分な場合があります
- 評価指標の標準偏差: そこで補助的に使うのが、目的関数(抗力係数など)を直近ステップにわたって監視し、その標準偏差(または平均に対する変動係数)が閾値を下回っているかという統計的な収束判定です。残差が下げ止まっていても評価指標が振動し続けている場合、この基準で未収束と判定できます
ゲートの設計例
一般的には、これらの指標を「即除外(ハードフェイル)」と「要確認フラグ(ソフトフェイル)」の2段階に分けて運用します。
| チェック項目 | 指標 | 基準例 | 判定 |
|---|---|---|---|
| メッシュ生成 | 負体積セル数 | 0件 | 超過で即除外 |
| メッシュ品質 | 最大スキューネス | 0.95未満 | 超過で即除外 |
| 収束性(残差) | 連続の式・運動量式の残差 | 最終値が未満 | 未達で除外 |
| 統計的収束 | 評価指標の変動係数(直近ステップ) | 1%未満 | 超過は要確認フラグ |
即除外にする項目は「解析として成立していない」ことを示す指標(負体積セル、明らかな発散)に限定し、統計的収束の基準をわずかに超える程度の境界線上のケースは自動除外せず「要確認」として人間の目に回す、という運用がバランスが良いと感じています。 すべてを自動で振り分けようとすると、閾値の設定ミス1つで有効なデータまで大量に削ってしまうリスクがあるためです。
閾値そのものは対象とする流れ場や要求精度によって変わるため、上の数値はあくまで一例です。 重要なのは、こうした基準をコードとしてパイプラインに組み込み、毎回同じ基準で機械的に判定できるようにしておくことです。
MLOps — 継続的に回す仕組み
AI Readyな1件のデータを作れることと、それを継続的に・信頼できる形で作り続けられることは別の話です。 後者を支えるのがMLOps的な発想です。
- 実験管理: パラメータ(設計変数、ソルバー設定)と結果(目的関数、収束履歴、生成物のパス)をセットで記録するのは、MLの実験管理(MLflowなど)とCFDのパラメトリックスタディで本質的に同じ作業です。CFD側でもこの発想を輸入し、ケースごとの入出力をひとつのレコードとして記録します
- データ・計算設定のバージョニング: メッシュやフィールドデータは容量が大きく、コードのようにgitで素直に管理できません。DVCのような発想で、「どのメッシュ生成ロジックのバージョンで作ったデータか」をコードのバージョンと紐付けて追跡できるようにします。計算設定側にも同じ問題があり、STAR-CCM+など市販ソフトウェアのケースファイル(
.simなど)はベンダー固有のバイナリ形式で、ソフトウェアライセンスがないと中身を読むことすらできず、差分も取れません。境界条件やソルバー設定を、ライセンス不要で誰でも参照できるHTMLなどの形式でエクスポートしておけば、テキストとして差分が取れるようになり、「前回のケースから何を変えたのか」を計算設定レベルで追跡できます - パイプラインのコード化: CFD最適化システムのクラス設計で扱った
ShapeGenerator → Solver → Evaluatorのループを、手元のスクリプトではなくバッチ実行基盤の上に載せ、失敗したケースだけを再実行できるようにします - 環境の固定: ソルバーのバージョンやライブラリ構成をコンテナ化し、半年前に作ったデータと今日作るデータが同じ条件で生成されることを担保します
これらは目新しい概念ではなく、MLOpsの語彙をCFDのワークフローに当てはめ直しているだけです。 それでも当てはめてみると、「実験管理をしていなかった」「バージョンが特定できないデータが混ざっている」といった穴が意外なほど見つかります。
データのレイヤー分け
実務では、生データから学習用データセットまでを1段階で作らず、いくつかのレイヤーに分けておくと扱いやすくなります。
diagram rendering…
- Raw: ソルバーがそのまま吐き出すファイル群。加工はせず、再現性のために保持する
- Curated: メタデータスキーマを付与し、品質ゲートを通過したケースのみが進む層。ここで初めて「学習に使ってよいデータ」になる
- ML-ready: 採用するアーキテクチャ(CNN/PointNet/GNNなど)に合わせて、格子への再サンプリングや点群化・グラフ化まで済ませた層
- 学習データセット: train/val/testに分割し、実際の学習ジョブから参照される最終形
レイヤーを分けておく利点は、後段の都合(アーキテクチャの変更、品質ゲートの基準見直し)が生じたときに、Rawまで遡らずCuratedからやり直せることです。 逆にレイヤーを分けずに生データから直接学習データセットを作っていると、基準を1つ変えるたびに全ケースを再解析する羽目になりかねません。
おわりに
CFDの精度を上げる努力と、そのデータを大量に・継続的に・信頼できる形で貯めていく設計は、別の技術です。 後者を怠ると、どれだけ良いサロゲートモデルのアーキテクチャを選んでも、土台のデータが「どう作られたか分からない」「品質にばらつきがある」状態のままでは実力を発揮できません。
メタデータのスキーマ化とレイヤー分けというシンプルな仕組みだけでも、後から「このデータ点は信頼できるか」を機械的に判定できるようになります。 最適化やサロゲート学習の規模が大きくなるほど、この土台の有無が効いてくると感じています。
