OpenFOAM

【OpenFOAMとOpenMoelica連携(2)】OpenFOAMとOpenMoelicaの連携:buoyantPimpleFoamソルバ

こんにちは(@t_kun_kamakiri

前回の記事ではOpenModelicaのコマンド実行の方法について紹介しました。

本記事は、OpenFOAMとOpenModelicaを連携させた計算方法を紹介する記事です。

OpenFOAMとOpenModelicaの連携にはFMUI規格に沿った、FMU4FOAMというツールがあります。
以下の記事を1つずつ読み進めていけば、FMU4FOAMを使うことができます。
この記事はOpenFOAMのv2412でも動かせるようにしたものです。
※並列計算できるかなどは確認していません。

ただし、このFMU4FOAMは現時点(2025年11月)で調べた限りはOpenFOAMのマルチリージョンソルバには対応していないようでした。

これが少し不満でどうしてもマルチリージョンソルバに対応したOpenFOAMとOpenModelicaの連携がしたく、上記の勉強会でも報告しアドバイスを頂いましたが、解決にはいたらず。
マルチリージョンソルバは以下の図のように領域ごとに「0, constant, system」ファイルを構成するため、FMU4FOAMの境界条件がこのファイル構造を認識するようにプログラムされていないことが原因のようです。

今回はマルチリージョンソルバへの対応のために、OpenFOAMと外部ソルバ(今回はOpenModelica)との連携ができるプログラムを実装する手順を考えたので紹介します。

やりたいこと

OpenFOAMから外部ソルバ(今回はOpenModelida)を実行し、OpenFOAMとOpenModelicaの連携を行います。
本記事では、まずはOpenModelicaのコマンド実行ができるようにします。

計算の流れは以下のようになります。

この仕組みを使ってFMU4FOAMの例題(heatedRoom)と同じことを行いました。
右下のグラフに結果を載せています。

 

一番左のグラフが大事で、OpenFOAMのprobesで指定した温度センサの値がオレンジ色のターゲット温度に追従するよう、OpenModelicaのPID制御で入口温度境界に反映させる設定にしています。

OpenFOAMと外部ソルバ(OpenMoelica)を連携

以下がFMU4FOAMによる結果です。

FMU4FOAM

じゃっかん結果が違いますが、やりたいことは達成していますよね。
OpenFOAMの流出温度の評価方法とPID制御のパラメータが少し違うことが原因なのかな?

というわけで前段が長くなりましたが、本記事ではFMU4FOAMを使わずOpenFOAMとOpenModelicaを連携させる方法についてまとめておきます。

  • OpenFOAM v2412
  • OpenModelica 1.25.0(Linux版)
  • WSL2(Ubuntu-22.04)

OpenModelicaの計算実行

前回の記事ではOpenModelicaをコマンド実行により計算する内容を紹介しました。

それぞれのファイルの関係性を図にしておきます。

これができるとものすごく便利ですよね。
なぜならOpenModelicaのGUIを起動することなく計算を実行できるため、数値を変更したパラスタやOpenFOAMの計算中に値をOpenModelicaに渡して計算を実行するなども可能になります。

OpenFOAMとOpenModelicaの連携の構成図

OpenFOAMとOpenModelicaを連成させる構成図を整理しました。

流れは以下です。

  1. system/controlDictのcodeExecuteにより特定の境界面の温度、特定の場所の温度を取得します。
  2. codeExecuteの途中でupdateMOS_and_Run.pyのPythonファイルを実行します。
    このファイルはHVACSystem002.mosを作成、run.shを実行を行うファイルです。
    run.shは前回の記事で説明したHVACSystem002.mosを実行するためのスクリプトです。
  3. HVACSystem002.mosには流入境界の値が記述されたboundarySyncFileも出力しています。
  4. boundarySyncFileに書かれた境界面の値を0/U, 0/Tファイルが読み込む

といった流れになります。

計算毎時に実行する独自プログラム

system/controlDictは計算毎時に独自のプログラムを実行するcodedという機能があります。
設定ファイルの全文を載せておきます。

system/controlDict

大事なのは#include "outletTempAverageValue";の部分です。
ここに独自のプログラムを書いておき、includeで読み込んでいます(直接記述すると煩雑になるためファイルを分けています)

特定の境界面の温度、特定の場所の温度を取得

outletTempAverageValueの全文を載せておきます。

いろいろ書いていますが、やっているのは以下の事です。

  1. 流量で重みづけしたoutlet境界面の温度$\overline{T} = \frac{\sum_i \rho v_iA_i C_p T_i}{\sum_i \rho v_iA_i C_p }= \frac{\sum_i \rho Q_i C_p T_i}{\sum_i \rho Q_i C_p }$を求める。
  2. 座標$(5, 5, 2.5)$の温度を所得
  3. それをconstant/outletWeightAreaTempFileファイルに記述
  4. updateMOS_and_Run.pyのPythonファイルを実行
    ただし、Pythonの実行が完全に終わるまで待機させる必要がある。事前にconstant/updateMOS.lockを作成しておき、Pythonファイルの実行が終わるとconstant/updateMOS.lockが削除される(この記述はupdateMOS_and_Run.pyに書かれている)ことでPythonの実行終了のフラグとしている。

途中作成されたconstant/outletWeightAreaTempFileは以下のような記述になる。

constant/outletWeightAreaTempFile

このToutTprobTimeOpenModelicaの実行時に必要な変数です。

1 2 3 4
関連記事もどうぞ

COMMENT