こんにちは(@t_kun_kamakiri)
🚀 OpenFOAMとOpenModelicaを連携して、より高度なシミュレーションを実現しませんか? 🚀
OpenFOAMは、オープンソースのCFD(数値流体力学)解析ソフトウェアとして広く使用されています。一方、OpenModelicaは、制御システムや機械・電気回路などのシステムシミュレーションに特化したツール です。これらを組み合わせることで、流体解析 + 制御モデルの連携 や、マルチフィジックス解析 が可能になります。
しかし、OpenFOAMとOpenModelicaを直接統合するのは容易ではありません。そこで登場するのが、FMU(Functional Mock-up Unit)を活用した「FMU4FOAM」 です。FMU4FOAMを利用すれば、FMI(Functional Mock-up Interface)規格に基づき、OpenFOAMでOpenModelicaのシミュレーションモデルを実行 できます。
本記事では、「OpenFOAMとOpenModelicaをFMUで連携する方法」 を初心者向けに詳しく解説します。インストールから設定、実際のシミュレーションの実行まで、エラー対策も含めて解説するので、この記事を読めばスムーズに統合解析ができるようになります!
- OpenFOAMとOpenModelicaの連携方法(FMU4FOAMの活用)
- FMUを使ったシミュレーション統合の手順
- よくあるエラーとその解決策
OpenFOAMとOpenModelicaとの連携を行うことで、どのようなことができるのかは以下の記事を読むと良いでしょう。
- OpenCAE_Simpo2022_竹とんぼ飛行シミュレーション
- 第38回Modelicaライブラリ勉強会「FMU4FOAMによる竹とんぼシミュレーション(その2)」
- FMU4FOAM:OpenFOAMとOpenModelicaの連成シミュレーションの紹介
それでは、さっそくOpenFOAMとOpenModelicaを連携する方法を見ていきましょう!
- WSL2(OpenFOAM v2412が使用できる状態)
- gitがインストールされている状態(gitコマンドが使用できる)
FMU4FOAMのビルド
FMUFOAMのビルドについて以下の記事を参考にしました。
git lab:FMU4FOAM(v2406以降対応)が比較的最新(2025/3/16時点)なので、これに沿ってビルドしていきます。
ただし、いくつかそのままでは上手く行かない部分があったので、それについても解説しながらビルドする手順を示します。
FMUFOAMのクローン
OpenFOAMの環境に入っていることを前提として始めます。
まずは適当なフォルダを作成してクローンします。
この記事では以下フォルダにクローンします。
1 |
/mnt/c/work/001_CAE/openfoam/20250315_FMU4FOAM |
20250315_FMU4FOAM
フォルダにいるものとして、以下のコマンドでクローンを作成します。
1 2 |
# Clone the repo git clone https://gitlab.com/foam-for-nuclear/FMU4FOAM.git |
クローンができたらFMU4FOAM
フォルダに移動します。
1 |
cd FMU4FOAM |
以下のコマンドで依存関係も含めてクローンします。
今回はECI4FOAM をクローンしています。
1 2 |
# Clone the submodules recursivly git submodule update --init --recursive |
準備ができました。
ここからgit lab:FMU4FOAM(v2406以降対応)のREADME.mdからビルドしていくのですが、はじめにECI4FOAMのビルドをしないと上手く行かなかったので、そちらからはじめます。
ECI4FOAMのビルド
こちらのECI4FOAMのREADME.mdを参考にインストールします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# Software library for encryption, decryption, signatures, password hashing, and more. sudo apt-get install libsodium-dev # Lightweight header-only library that exposes C++ types in Python and vice versa, mainly to create Python bindings of existing C++ code sudo apt-get install pybind11-dev # JSON library sudo apt-get install nlohmann-json3-dev # Lightweight messaging kernel based on ZeroMQ sudo apt-get install libzmq3-dev sudo apt-get install python3-dev # C++ Automated Test Cases in Headers sudo apt-get install catch2 python3 -m pip install oftest # Export variables for Python.h export CPATH=/usr/include/python3.10:$CPATH export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH |
次にlibzmq
と cppzmq
をシステムにインストールする必要があります。
作業場所はどこでも良いですが、以下のフォルダとします。
1 |
cd .. #/mnt/c/work/001_CAE/openfoam/20250315_FMU4FOAMフォルダに移動 |
ECI4FOAMではcd ~/Software
のようにHOMEディレクトリ
で作業していますが、WindowsからWSL2のHOMEディレクトリは見つけにくかったりするので、今回はCドライブにあるフォルダで作業をします。
※ちなみにHOMEディレクトリ
は\\wsl.localhost\Ubuntu-22.04\home
にあります。
まずは、lizmq
をビルドします。
zmq
1 2 3 4 5 6 7 8 |
# or git clone https://github.com/zeromq/libzmq.git cd libzmq mkdir build cd build cmake .. make -j4 sudo make -j4 install |
続いて、cppzmq
をビルドします。
1 |
cd ../../ |
cppzmq
1 2 3 4 5 6 7 |
git clone https://github.com/zeromq/cppzmq.git cd cppzmq mkdir build cd build cmake .. make -j4 sudo make -j4 install |
FMUFOAMのビルド
ここからFMU4FOAMに従ってビルドします。
1 |
cd ../../FMU4FOAM |
ではスクリプトを実行します。
1 2 3 |
# Init submodule ECI4FOAM and build # Depending on your system, you might install additional packages (see https://gitlab.com/foam-for-nuclear/ECI4FOAM for more details) ./build-ECI4FOAM.sh -j4 |
エラーが出たらどこでエラーが出ているかを確認すると良いです。
build-ECI4FOAM.shはそこまで難しいスクリプトではないので、スクリプト内のコマンドをひとつずつ実行してエラー箇所を特定すると良いでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#!/bin/sh cd "${0%/*}" || exit # Run from this directory #------------------------------------------------------------------------------- git submodule update --init --recursive # pip install oftest conan cd ECI4FOAM/ #install generator # cd OpenFOAMGen/OpenFOAMGen # conan export . myuser/OpenFOAMGen # cd ../.. # compile ECI4FOAM ./Allwmake $1 cd .. #------------------------------------------------------------------------------- |
続いて環境変数を設定しておきます。
1 2 |
# In ~/.bashrc export LIB_ECI4FOAM=$HOME/path/to/ECI4FOAM |
1 |
./Allwmake -j4 |
Allwmake
でもエラーが生じた場合は、スクリプト内のコマンドをひとつずつ実行してエラー箇所を特定すると良いでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#!/bin/bash #------------------------------------------------------------------------------- rootPath=$(pwd) # Check LIB_ECI4FOAM variable before build if [[ ! -z "$LIB_ECI4FOAM" ]] then echo "Found LIB_ECI4FOAM:= $LIB_ECI4FOAM" else echo "ERROR: LIB_ECI4FOAM environment variable not found" echo "Make sure to build ECI4FOAM and export LIB_ECI4FOAM in your ~/.bashrc" exit 1 fi # Build the FMU4FOAM Python package and install using pip cd src/FMU4FOAM/FMU4FOAM-export/ ./build_unix.sh cd $rootPath python3 -m pip install . # Build project ./src/OF_FMU/pyFMUSim/Allwmake $1 wmake $1 src/OF_FMU/FMU/ # Build applications # wmake $1 application/solver/solidFoamAdjustTime/ wmake $1 application/tools/dictModifier/ #------------------------------------------------------------------------------- |
ちなみに実行すると以下のようなエラーが出ました。
(おそらく皆さんの環境でも出るでしょう)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
ccDPInt32Opt/FMUSimulator.o In file included from FMUSimulator.C:20: FMUSimulator.H:52:10: fatal error: externalIOObjectList.H: No such file or directory 52 | #include "externalIOObjectList.H" | ^~~~~~~~~~~~~~~~~~~~~~~~ pyFMUSim.C:21:10: fatal error: pyInterp.H: No such file or directory 21 | #include "pyInterp.H" | ^~~~~~~~~~~~ compilation terminated. compilation terminated. make: *** [/usr/lib/openfoam/openfoam2412/wmake/rules/General/transform:38: Make/linux64GccDPInt32Opt/pyFMUSim.o] Error 1 make: *** Waiting for unfinished jobs.... make: *** [/usr/lib/openfoam/openfoam2412/wmake/rules/General/transform:38: Make/linux64GccDPInt32Opt/FMUSimulator.o] Error 1 Compiling enabled on 4 cores wmake src/OF_FMU/FMU g++ -std=c++17 -m64 -pthread -DOPENFOAM=2412 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate-depth-100 -I../pyFMUSim -I/home/kamakiri/path/to/ECI4FOAM/src/externalComm/lnInclude -I/usr/lib/openfoam/openfoam2412/src/finiteVolume/lnInclude -I/usr/lib/openfoam/openfoam2412/src/dynamicMesh/lnInclude -I/usr/lib/openfoam/openfoam2412/src/meshTools/lnInclude -I/usr/lib/openfoam/openfoam2412/src/functionObjects/field/lnInclude -I/usr/lib/openfoam/openfoam2412/src/functionObjects/forces/lnInclude -iquote. -IlnInclude -I/usr/lib/openfoam/openfoam2412/src/OpenFOAM/lnInclude -I/usr/lib/openfoam/openfoam2412/src/OSspecific/POSIX/lnInclude -fPIC -c FMUController.C -o Make/linux64GccDPInt32Opt/FMUController.o In file included from FMUController.C:20: FMUController.H:69:10: fatal error: zmq_socket.H: No such file or directory 69 | #include "zmq_socket.H" | ^~~~~~~~~~~~~~ |
これはFMU4FOAM/src/OF_FMU/FMUのビルド
で失敗しているようです。
パスがうまくリンクされていないためのエラーですので、以下のように修正します。
修正1:FMU4FOAM/src/OF_FMU/FMU/Make/options
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
EXE_INC = \ -I../pyFMUSim \ -I$(LIB_ECI4FOAM)/src/externalComm/lnInclude \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/functionObjects/field/lnInclude \ -I$(LIB_SRC)/functionObjects/forces/lnInclude LIB_LIBS = \ -lcompressibleTransportModels \ -lfiniteVolume \ -lmeshTools \ -L$(FOAM_USER_LIBBIN) \ -lexternalComm \ -lzmq |
以下のように修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
EXE_INC = \ -I../pyFMUSim \ -I../../../ECI4FOAM/src/externalComm/lnInclude \ #←ここを修正 -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/dynamicMesh/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_SRC)/functionObjects/field/lnInclude \ -I$(LIB_SRC)/functionObjects/forces/lnInclude LIB_LIBS = \ -lcompressibleTransportModels \ -lfiniteVolume \ -lmeshTools \ -L$(FOAM_USER_LIBBIN) \ -lexternalComm \ -lzmq |
修正2:FMU4FOAM/src/OF_FMU/pyFMUSim/Make/options
1 2 3 4 5 6 7 8 9 10 11 12 13 |
EXE_INC = \ -Wno-old-style-cast \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I$(LIB_ECI4FOAM)/src/externalComm/lnInclude \ -I$(LIB_ECI4FOAM)/src/embeddingPython/lnInclude LIB_LIBS = \ -L$(FOAM_USER_LIBBIN) \ -lembPython \ -lexternalComm \ -lfiniteVolume \ -lmeshTools |
以下のように修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
EXE_INC = \ -Wno-old-style-cast \ -I$(LIB_SRC)/finiteVolume/lnInclude \ -I$(LIB_SRC)/meshTools/lnInclude \ -I../../../ECI4FOAM/src/externalComm/lnInclude \ #←ここを修正 -I../../../ECI4FOAM/src/embeddingPython/lnInclude #←ここを修正 LIB_LIBS = \ -L$(FOAM_USER_LIBBIN) \ -lembPython \ -lexternalComm \ -lfiniteVolume \ -lmeshTools |
再度Allwmake -j4
を実行すると上手く行きます。
1 |
./Allwmake -j4 |
warningなどが出ますがエラーではないので問題なくビルドできます。
Allwmakeにより以下の$FOAM_USER_LIBBIN
フォルダにライブラリが生成されています。以下のように生成されていれば成功です!
1 2 |
kamakiri$ ls $FOAM_USER_LIBBIN libFMUController.so libembPython.so libexternalComm.so libpyFMUSim.so |
※$FOAM_USER_LIBBIN = /home/kamakiri/OpenFOAM/kamakiri-v2412/platforms/linux64GccDPInt32Opt/lib
手順的には以下のコマンドで環境変数の設定をしているようですが、たぶん不要です。
1 2 |
# In ~/.bashrc export LIB_FMU4FOAM=$HOME/path/to/FMU4FOAM |
例題:Temperature Control in a Flange
では、例題を実行してみましょう。
OpenModelicaのモデル部分がこちらです。
元々のOpenModelicaで用意されている例題は以下のように熱伝導によって温度を検知し(温度計測)、rampで設定した温度(グラフの赤線)との温度差が2℃以上である場合は、電気回路のスイッチをオンに切り替え、電流が流れることで発熱を起こしheatCapacititorに熱量を与えるというモデルです。
「Temperature Control in a Flange」のモデルは熱伝導の部分のinput情報をOpenFOAM側で行っているということです。
OpenFOAMとOpenModelicaの連携のための設定はこちらに詳細の解説があります。
例題の実行
OpenModelicaをPythonで操作するライブラリをインストールします。
1 |
python3 -m pip install OMSimulator |
インストールができたら、フォルダを移動移動します。
1 |
cd examples/TempControlFlange/ |
Allrun
スクリプトを実行して計算させます。
1 |
./Allrun |
エラーが出たらAllrun
スクリプトの中身をひとつずつ実行してエラー箇所を特定すると良いでしょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#!/bin/sh cd "${0%/*}" || exit # Run from this directory . ${WM_PROJECT_DIR:?}/bin/tools/RunFunctions # Tutorial run functions #------------------------------------------------------------------------------ touch flange.foam echo ${FOAM_TUTORIALS:?} runApplication ansysToFoam \ ${FOAM_TUTORIALS:?}/resources/geometry/flange.ans -scale 0.001 runApplication $(getApplication) #------------------------------------------------------------------------------ |
controlledTemperature.csv
ファイルが出力されていれば成功です。
1 2 3 4 5 6 7 8 9 10 |
time,model.root.system1.Qout,model.root.system1.TRes,model.root.system1.Tin,model.root.system1.dTin,model.root.system1.ground.p.i,model.root.system1.ground.p.v,model.root.system1.heatingResistor.R,model.root.system1.heatingResistor.v,model.root.system1.idealSwitch.LossPower,model.root.system1.idealSwitch.T_heatPort,model.root.system1.idealSwitch.i,model.root.system1.idealSwitch.s,model.root.system1.idealSwitch.v,model.root.system1.ramp.y,model.root.system1.temperatureSensor.port.Q_flow,model.root.system1.temperatureToHeatFlowAdaptor.u2,model.root.system1.temperatureToHeatFlowAdaptor.y1,model.root.system1.temperatureToHeatFlowAdaptor.y2,model.root.system1.constantVoltage.p.v,model.root.system1.constantVoltage.v,model.root.system1.heatingResistor.T,model.root.system1.idealSwitch.T,model.root.system1.idealSwitch.p.v,model.root.system1.onOffController.bandwidth,model.root.system1.constantVoltage.i,model.root.system1.constantVoltage.n.i,model.root.system1.constantVoltage.n.v,model.root.system1.constantVoltage.p.i,model.root.system1.heatingResistor.LossPower,model.root.system1.heatingResistor.T_heatPort,model.root.system1.heatingResistor.heatPort.Q_flow,model.root.system1.heatingResistor.heatPort.T,model.root.system1.heatingResistor.i,model.root.system1.heatingResistor.n.i,model.root.system1.heatingResistor.n.v,model.root.system1.heatingResistor.p.i,model.root.system1.heatingResistor.p.v,model.root.system1.idealSwitch.n.i,model.root.system1.idealSwitch.n.v,model.root.system1.idealSwitch.p.i,model.root.system1.onOffController.reference,model.root.system1.onOffController.u,model.root.system1.temperatureSensor.T,model.root.system1.temperatureSensor.port.T,model.root.system1.temperatureToHeatFlowAdaptor.f,model.root.system1.temperatureToHeatFlowAdaptor.heatPort.Q_flow,model.root.system1.temperatureToHeatFlowAdaptor.heatPort.T,model.root.system1.temperatureToHeatFlowAdaptor.p,model.root.system1.temperatureToHeatFlowAdaptor.pder,model.root.system1.temperatureToHeatFlowAdaptor.u,model.root.system1.temperatureToHeatFlowAdaptor.u1,model.root.system1.temperatureToHeatFlowAdaptor.y,model.root.system1.onOffController.y,model.root.system1.heatingResistor.useHeatPort,model.root.system1.idealSwitch.useHeatPort,model.root.system1.temperatureToHeatFlowAdaptor.use_fder,model.root.system1.temperatureToHeatFlowAdaptor.use_fder2,model.root.system1.temperatureToHeatFlowAdaptor.use_pder,model.root.system1.temperatureToHeatFlowAdaptor.use_pder2,model.root.system1.idealSwitch.control,model.root.system1.idealSwitch.off,model.root.system1.logicalNot.u,model.root.system1.logicalNot.y 0, -2.54702989848e-12, 298, 298, 0, 0, 0, 10.1901960784, 5.09457889164e-06, 2.49949056807e-08, 293.15, 4.99949054211e-07, 0.0499949054211, 0.0499949054211, 298.15, 0, 0, 0, 0, 0.05, 0.05, 293.15, 293.15, 0.05, 2, -4.99949054211e-07, 4.99949054211e-07, 0, -4.99949054211e-07, 2.54702989848e-12, 298, -2.54702989848e-12, 298, 4.99949054211e-07, -4.99949054211e-07, 0, 4.99949054211e-07, 5.09457889164e-06, -4.99949054211e-07, 5.09457889164e-06, 4.99949054211e-07, 298.15, 298, 298, 298, -2.54702989848e-12, 2.54702989848e-12, 298, 298, 0, 298, 0, 2.54702989848e-12, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1 0.001, -2.54702989848e-12, 298, 298, 0, 0, 0, 10.1901960784, 5.09457889164e-06, 2.49949056807e-08, 293.15, 4.99949054211e-07, 0.0499949054211, 0.0499949054211, 298.15, 0, 0, 0, 0, 0.05, 0.05, 293.15, 293.15, 0.05, 2, -4.99949054211e-07, 4.99949054211e-07, 0, -4.99949054211e-07, 2.54702989848e-12, 298, -2.54702989848e-12, 298, 4.99949054211e-07, -4.99949054211e-07, 0, 4.99949054211e-07, 5.09457889164e-06, -4.99949054211e-07, 5.09457889164e-06, 4.99949054211e-07, 298.15, 298, 298, 298, -2.54702989848e-12, 2.54702989848e-12, 298, 298, 0, 298, 0, 2.54702989848e-12, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1 0.001, -2.54702989848e-12, 298, 298, 0, 0, 0, 10.1901960784, 5.09457889164e-06, 2.49949056807e-08, 293.15, 4.99949054211e-07, 0.0499949054211, 0.0499949054211, 298.15, 0, 0, 0, 0, 0.05, 0.05, 293.15, 293.15, 0.05, 2, -4.99949054211e-07, 4.99949054211e-07, 0, -4.99949054211e-07, 2.54702989848e-12, 298, -2.54702989848e-12, 298, 4.99949054211e-07, -4.99949054211e-07, 0, 4.99949054211e-07, 5.09457889164e-06, -4.99949054211e-07, 5.09457889164e-06, 4.99949054211e-07, 298.15, 298, 298, 298, -2.54702989848e-12, 2.54702989848e-12, 298, 298, 0, 298, 0, 2.54702989848e-12, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1 0.002, -2.54702989848e-12, 298, 298, 0, 0, 0, 10.1901960784, 5.09457889164e-06, 2.49949056807e-08, 293.15, 4.99949054211e-07, 0.0499949054211, 0.0499949054211, 298.15, 0, 0, 0, 0, 0.05, 0.05, 293.15, 293.15, 0.05, 2, -4.99949054211e-07, 4.99949054211e-07, 0, -4.99949054211e-07, 2.54702989848e-12, 298, -2.54702989848e-12, 298, 4.99949054211e-07, -4.99949054211e-07, 0, 4.99949054211e-07, 5.09457889164e-06, -4.99949054211e-07, 5.09457889164e-06, 4.99949054211e-07, 298.15, 298, 298, 298, -2.54702989848e-12, 2.54702989848e-12, 298, 298, 0, 298, 0, 2.54702989848e-12, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1 0.002, -2.54702989848e-12, 298, 298, 0, 0, 0, 10.1901960784, 5.09457889164e-06, 2.49949056807e-08, 293.15, 4.99949054211e-07, 0.0499949054211, 0.0499949054211, 298.15, 0, 0, 0, 0, 0.05, 0.05, 293.15, 293.15, 0.05, 2, -4.99949054211e-07, 4.99949054211e-07, 0, -4.99949054211e-07, 2.54702989848e-12, 298, -2.54702989848e-12, 298, 4.99949054211e-07, -4.99949054211e-07, 0, 4.99949054211e-07, 5.09457889164e-06, -4.99949054211e-07, 5.09457889164e-06, 4.99949054211e-07, 298.15, 298, 298, 298, -2.54702989848e-12, 2.54702989848e-12, 298, 298, 0, 298, 0, 2.54702989848e-12, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1 0.003, -2.54702989848e-12, 298, 298, 0, 0, 0, 10.1901960784, 5.09457889164e-06, 2.49949056807e-08, 293.15, 4.99949054211e-07, 0.0499949054211, 0.0499949054211, 298.15, 0, 0, 0, 0, 0.05, 0.05, 293.15, 293.15, 0.05, 2, -4.99949054211e-07, 4.99949054211e-07, 0, -4.99949054211e-07, 2.54702989848e-12, 298, -2.54702989848e-12, 298, 4.99949054211e-07, -4.99949054211e-07, 0, 4.99949054211e-07, 5.09457889164e-06, -4.99949054211e-07, 5.09457889164e-06, 4.99949054211e-07, 298.15, 298, 298, 298, -2.54702989848e-12, 2.54702989848e-12, 298, 298, 0, 298, 0, 2.54702989848e-12, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1 0.003, -2.54702989848e-12, 298, 298, 0, 0, 0, 10.1901960784, 5.09457889164e-06, 2.49949056807e-08, 293.15, 4.99949054211e-07, 0.0499949054211, 0.0499949054211, 298.15, 0, 0, 0, 0, 0.05, 0.05, 293.15, 293.15, 0.05, 2, -4.99949054211e-07, 4.99949054211e-07, 0, -4.99949054211e-07, 2.54702989848e-12, 298, -2.54702989848e-12, 298, 4.99949054211e-07, -4.99949054211e-07, 0, 4.99949054211e-07, 5.09457889164e-06, -4.99949054211e-07, 5.09457889164e-06, 4.99949054211e-07, 298.15, 298, 298, 298, -2.54702989848e-12, 2.54702989848e-12, 298, 298, 0, 298, 0, 2.54702989848e-12, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1 0.004, -2.54702989848e-12, 298, 298, 0, 0, 0, 10.1901960784, 5.09457889164e-06, 2.49949056807e-08, 293.15, 4.99949054211e-07, 0.0499949054211, 0.0499949054211, 298.15, 0, 0, 0, 0, 0.05, 0.05, 293.15, 293.15, 0.05, 2, -4.99949054211e-07, 4.99949054211e-07, 0, -4.99949054211e-07, 2.54702989848e-12, 298, -2.54702989848e-12, 298, 4.99949054211e-07, -4.99949054211e-07, 0, 4.99949054211e-07, 5.09457889164e-06, -4.99949054211e-07, 5.09457889164e-06, 4.99949054211e-07, 298.15, 298, 298, 298, -2.54702989848e-12, 2.54702989848e-12, 298, 298, 0, 298, 0, 2.54702989848e-12, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1 ...(省略)... |
あとはグラフにするためにPythonプログラムを使用していますので、実行します。
1 |
python3 Allplot.py |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
""" Plot results from csv file. """ #==============================================================================* # Imports import pandas as pd import matplotlib.pyplot as plt #==============================================================================* # Read the data T = pd.read_csv("controlledTemperature.csv") T["diff"] = abs(T["model.root.system1.Tin"] - T["model.root.system1.ramp.y"]) print(f"Max Tdiff = {T['diff'].max()} K") # Plots figT, axT = plt.subplots() figTdiff, axTdiff = plt.subplots() figQ, axQ = plt.subplots() axT.plot(T["time"], T["model.root.system1.Tin"], label="Tin") axT.plot(T["time"], T["model.root.system1.ramp.y"], label="Target") axT.set_ylabel("Temperature [K]") axTdiff.plot(T["time"], T["diff"], label="Tin - ramp") axTdiff.set_ylabel("Temperature difference [K]") axQ.plot(T["time"], T["model.root.system1.Qout"], label="Qout") axQ.set_ylabel("Power [W]") # Common features for fig, ax in zip([figT, figTdiff, figQ], [axT, axTdiff, axQ]): ax.set_xlabel("Time [s]") ax.legend() fig.tight_layout() figT.savefig("results/T.png") figTdiff.savefig("results/Tdiff.png") figQ.savefig("results/Q.png") # plt.show() #==============================================================================* |
※padasのバージョンによってはaxT.plot(T["time"].to_numpy, T["model.root.system1.Tin"].to_numpy, label="Tin")
のようにSeries型をnumpy型に変換しないとエラーになる場合があります。
以上でFMU4FOAMのビルドと例題の実行の解説を終わります。
まとめ
今回の記事では、OpenFOAMとOpenModelicaをFMU4FOAMを使って連携する方法 を詳しく解説しました。まず、libzmq
や cppzmq
などの依存ライブラリをインストールし、ECI4FOAMをビルドした後、Allwmake -j4
を実行してFMU4FOAMをコンパイルしました。
その後、例題「Temperature Control in a Flange」を実行し、controlledTemperature.csv
が正しく出力されることを確認しました。さらに、Pythonスクリプト Allplot.py
を使用してシミュレーション結果を可視化し、データ分析まで行いました。これにより、OpenFOAMとOpenModelicaの連携手順や、FMUを活用したシミュレーションの流れが理解できるようになり、実際の計算環境を構築するスキルが身につきます。
OpenFOAMを使った制御系やマルチフィジックス解析に興味がある方にとって、FMU4FOAMの導入手順やエラー解決のポイントが明確になり、スムーズにセットアップできるようになります。
計算力学技術者のための問題アプリ
計算力学技術者熱流体2級、1級対策アプリをリリースしました。
- 下記をクリックしてホームページでダウンロードできます。
- LINE公式に登録すると無料で問題の一部を閲覧できます。
※LINEの仕様で数式がずれていますが、アプリでは問題ありません。
- 計算力学技術者の熱流体2級問題アプリ作成
リリース後も試行錯誤をしながら改善に努め日々アップデートしています。
備忘録として作成の過程を綴っています。
OpenFOAMに関する技術書を販売中!
OpenFOAMを自宅で学べるシリーズを販売中です。
OpenFOAM初学者から中級者向けの技術書となっていますので、ぜひよろしくお願いいたします。
次回の技術書典18に向けて内容を考え中です。
乞うご期待!!
おすすめ参考図書
☟こちらは、OpenFOAMの日本語書籍が無い中唯一わかりやすい参考書だと思います。
☟こちらもOpenFOMの古いバージョンでの和訳になります。さすがにこちらはバージョンに対する日本語でのケアはしていないので、OpenFOAMに慣れている方は購入しても良いかと思います。僕は「日本語でまとまっている内容」なので少し重宝しています。
☟以下に、もっと初心者向けの同人誌を紹介しておきます。
初心者は「ってか、まずどうやってOpenFOAMをインストールするの?」というところからつまずきがちです。
そんな時は、以下の書籍をおすすめします。
改訂新版 OpenFOAMの歩き方 (技術の泉シリーズ(NextPublishing))
インストール方法とチュートリアルで流体解析を体験・・・ちょっと高度な解析まで解説があります。著者曰くOpenFOAMのバージョンの追跡を行いながら、書籍をアップデートするようなので安心ですね。