DEXCSランチャー v2.5 製作メモ/ 3

3 DEXCS ワークベンチ / ランチャー化へ向けての取り組み



まずは、残差プロットの仕組みを、 CfdOF ワークベンチを切り離して使えないものかを調べてみた。メッ
シュ作成からケースセットアップまでは、現行の DEXCS ランチャーで実施できているという前提である。

3.1 残差プロット 1

DEXCS ランチャーにおける[plotWatcher の起動 ] (残差プロット表示)は、 runPlotWatcher.py で、
PyFoam の pyFoamPlotWatcher.py を起動できるようにしたものであった (94 〜 109 行目 ) 。

94: cont = "#!/bin/bash\n"
95: cont = cont + ". " + envOpenFOAMFix + "\n"
96: cont = cont + ’echo -n "running plotWatcher"\n’
97: cont = cont + "pyFoamPlotWatcher.py " + logFile + " 1> /dev/null 2> /dev/null\n"
98: f = open("plotWatcher", "w")
99: f.write(cont)
100: f.close()
101: os.system("chmod a+x plotWatcher")
102: title = solveCaseFix
103: if len(title) > 30:
104: title = "_..." + title[-30:]
105: title = "plotWatcher:" + title
106: #comm = "gnome-terminal --name=" + title + " --geometry=80x2 --hide-menubar -x bash --rcfil
107: comm = "gnome-terminal --name=" + title + " --geometry=80x2 --hide-menubar -- bash --rcfile
108: os.system(comm)
109: 9os.chdir(saveDir)

この部分を以下のように書き換えた。

156:
#print(logFile)
157:
158: UxResiduals = []
159: UyResiduals = []
160: UzResiduals = []
161: pResiduals = []
162: rhoResiduals = []
163: EResiduals = []
164: kResiduals = []
165: omegaResiduals = []
166: niter = 0
167: itimer=1
168:
169: residualPlot = ResidualPlot()
170:
171: #Timer.setInterval(2000)
172: #Timer.timeout.connect(_plotResidual(logFile, niter))
173: #Timer.start()
174: #while itimer:
175: _plotResidual(logFile, niter)
176: #sleep(2)
177: #_plotResidual(logFile, niter)
178: #sleep(2)
179: #_plotResidual(logFile, niter)
180: #sleep(2)

169 行目で、 ResidualPlot() を呼び出しているが、この段階では CfdOF モジュールとのは考えていないので、
便宜的に CfdOF モジュール中の、 CfdResidualPlot.py と同じ内容で、 dexcsCfdResidualPlot.py を用意し
て、 12 行目

from dexcsCfdResidualPlot import ResidualPlot

で使えるようにした。また、 175 行目 plotResidual(logFile, niter) の実体は、

113: def _plotResidual(logFile, niter):
114: print("log=",logFile)
115: f=open(modelDir+"/"+logFile)
116: loglines = f.readlines()
117: #f.close()
118: process_output(loglines, niter)
119: residualPlot.updateResiduals

logFile を読み込んで、その内容を process output(loglines, niter) に渡して、 residualPlot.updateResiduals
(プロット図をアップデート)しようとするもので、 CfdRunnableFoam.py 中のそれを真似して作成したもの
である。 process output(loglines, niter) も、 CfdOF モジュールとの連携を考えていないので、

66: def process_output(text, niter):
67: itimer = 0
68: for line in text:
69: #print(line),
70: split = line.split()
71:
72: # Only store the first residual per timestep
73: if line.startswith(u"Time = "):
74: niter += 1
75:
76: # print split
77: if "Ux," in split and niter-1 > len(UxResiduals):
78: UxResiduals.append(float(split[7].split(’,’)[0]))
79: if "Uy," in split and niter-1 > len(UyResiduals):
80: ... 以下省略 ...

と、 CfdOF モジュールの CfdRunnableFoam.py 中の 102 行目 def process output(self,text) の内容をほと
んどそのまま流用した。 CfdOF オリジナルからの変更点として、引数として niter を加えてあるが、これは
イタレーション回数を見ながら自動更新処理を出来ないかと工夫の名残りである。また、 171 行目〜 180 行目
でコメントアウトした行も、同じ目的で試行錯誤したもので、現時点で自動更新処理は出来ていないので、こ
れらの部分は不要である。
以上の改変にて、残差プロットは CfdOF と同じものを表示できるようになった(見栄えは良くなった!)。
但し、上記説明の中で記したように、計算の開始直後にこれを起動して、計算の進行とともに自動更新処理を
させようと試みたが、実現できていない。
ここで一旦、自動更新の試みを断念して、次節では別のアプローチで残差グラフ表示に取り組むこととする
が、その前に本節の取り組みで判ったことを記しておく。

判明項目17

CfdOF の残差プロットは、計算実行時の標準出力をモニターしているのに対して、今回試みたのは、
実行ログファイルの内容を読み直す方法であり、これでは無理っぽい。

判明項目18


PyFoam の plotWatcher.py はログファイルを監視しつつ更新している(多分、読み直したりはしてい
ない)ので、その方法に習えば、実現できる可能性もあるので、改めて調査予定。

判明項目19

DEXCS ランチャーで、 postProcessing フォルダ中に出力されるデータをプロットするのに、 JGNPlot
を使っているが、 CfdResidualPlot.py を参考に Plot ワークベンチで代用することはできるかもしれな
いので、これも改めて調査予定。

前へ 目次 次へ

DEXCSランチャー v2.5 製作メモ / 2. 4



2.4 CdfOFのソースコードと主要プログラムの動作メカニズム

FreeCAD に対して拡張したワークベンチは、 .FreeCAD/Mod フォルダ中に収納される。 Mod フォルダ下
には、 CfdOF フォルダと Plot フォルダがあり、それぞれのコードが収納される。
Mod フォルダ下には、以下のファイルとサブフォルダ( Gui, pycashe , data, testFiles )が存在する。

├── CfdAnalysis.py
├── CfdCaseWriterFoam.py
├── CfdConsoleProcess.py
├── CfdFaceSelectWidget.py
├── CfdFluidBoundary.py
├── CfdFluidMaterial.py
├── CfdInitialiseFlowField.py
├── CfdMesh.py
├── CfdMeshRefinement.py
├── CfdMeshTools.py
├── CfdPhysicsSelection.py
├── CfdPreferencePage.py
├── CfdPreferencePage.ui
├── CfdResidualPlot.py
├── CfdRunnableFoam.py
├── CfdSolverFoam.py
├── CfdTools.py
├── CfdZone.py
├── Init.py
├── InitGui.py
├── README.md
├── TaskPanelCfdFluidBoundary.ui
├── TaskPanelCfdFluidProperties.ui
├── TaskPanelCfdInitialiseInternalField.ui
├── TaskPanelCfdListOfFaces.ui
├── TaskPanelCfdMesh.ui
├── TaskPanelCfdMeshRefinement.ui
├── TaskPanelCfdSolverControl.ui
├── TaskPanelCfdZone.ui
├── TaskPanelPhysics.ui
├── TemplateBuilder.py
├── TestCfd.py
├── WindowsRunWrapper.py
├── _TaskPanelCfdFluidBoundary.py
├── _TaskPanelCfdFluidProperties.py
├── _TaskPanelCfdInitialiseInternalFlowField.py
├── _TaskPanelCfdMesh.py
├── _TaskPanelCfdMeshRefinement.py
├── _TaskPanelCfdPhysicsSelection.py
├── _TaskPanelCfdSolverControl.py
├── _TaskPanelCfdZone.py
├── metadata.txt

Plot ワークベンチに関しては、 Mod/Plot フォルダ下、 freecad/plot フォルダ中に以下の python コード
と、他にもいくつかのサブフォルダに分けてコードが収納されており、コードの収納方法に決まりは無いよう
である。

├── CMakeLists.txt
├── Plot.py
├── PlotGui.py
├── Plot_rc.py
├── __init__.py
├── compile_resources.py
├── freecad_backend.py
├── init_gui.py
├── plot.dox
└── version.py

どういうイベントでどのプログラムが起動されるのかという、コードの動作原理についてはまだ十分解明できていないが、現時点で判っていることを以下に記しておく。

判明項目1

メッシュ作成および解析実行ケースは、 Default output directory 下の meshcase, case フォルダにそれぞれ収納される仕組みとなっており、 Default output directory は、デフォルトでは /tmp となるが、「編集」⇒「設定」メニューにより、任意に指定は可能。

判明項目2

CfdOF ワークベンチが選択されると、 InitGui.py 中の cmdlist に定義した内容にしたがって、ツールバーのボタンと、ボタンが押された時の実行メニューが割り当てられ、ツールバーが表示される(どういう仕組みで InitGui.py が起動されるのかはわかっていない)。

判明項目3

ツールバー中の CfdAnalysis ボタンを押すと、 CfdAnalysis.py の CommandCfdAnalysis() が実行され、コンボビューに 4 つのコンテナ( PhysicsModel, FluidProperties, InitialFields, CfdSolver )が追加表示される。

判明項目4

コンボビュー上の Part オブジェクトをどれか一つを選択すると、ツールボタンの [Create a mesh usinf…] ボタンがアクティブになるので、これをクリックすると選択した Part オブジェクトを対象にfluidRegion_ Mesh コンテナが作成され、 [CFD Mesh] タスク画面が現れて、メッシュの制御(ケー ス作成、実行、表示)ボタンが使えるようになる(⇒ TaskPanelCfdMesh.py )。

判明項目5

Mesh Parameters として、 3D/2D の選択、 cfMesh/snappyHexMesh/gmsh の選択が可能で、選択に 応じてタスク画面の下部表示内容が変化する。

判明項目6

タスク画面を閉じて、モデルツリー上の fluidRegion_Mesh コンテナを選択すると、ツールボタンの [Creates a mesh refinement] ボタンがアクティブになるので、これをクリックすると [Meshrefinement] タスク画面が現れて、メッシュの細分化設定が可能になる。ここで着目したいのが、細分化対象の設定方法である(図 8 )。本来は、先にパーツを選択して、右クリックメニューなどでこの画面を出したいところであるが、かような方法であれば許容範囲でないかと思われる。

図 8 細分化対象パーツの設定
判明項目7

細分化指定のもう一つの方法、図 9 InternalVolume についても、同様に パーツ選択するだけで、プロパティに登録されるようになっているが、この設定は snappyHexMesh の場合に有効であるが、このコンテナが存在する状態で cfMesh を作成しようとするとエラーになってしまう。

図9 領域細分化の設定
判明項目8

openSimで公開されているチュートリアル資料「 CFD Tutorial 4 – External Aerodynamics of a UAV.pdf」によれば、 [Mesh region] というタスク画面で、 cfMesh 用のプリミティブ定義メニュー(図 10 )を使えているのだが、現行モジュールではこのタスク画面が出てこない。というか、タスク画面の名前そのものが異なっている。

図 10 領域細分化の設定 [Mesh region] タスク画面
判明項目9

図 9 で設定が完了し [ 閉じる ] をクリックすると、コンボビュー上でコンテナに対するプロパティとして登録されるようになる(図 9 の右下赤破線の四角枠内)。上述の cfMesh の region 設定に係る不具合もあって現行の設定メニューをそのまま使うことはできないが、このようにパーツ毎の設定情報をFreeCAD モデル本体に具現することができれば、現行 DEXCS でやっているような meshDict を読み込み直して設定を再現するという回りくどいやり方をしないで済むようになるということである。

判明項目10

CfdSolver コンテナをダブルクリックすると、 [Analysis control] タスク画面が現れる( TaskPanelCfdControl.py )。Case[Write] ボタンをクリックすればケースファイルが作られて、 Solver[Run] ボタンがアクティブになるので、それをクリックすれば計算が開始すると同時に、残差グラフが現れて、その表示内容が計算の進行とともに更新されていく。

判明項目11

Case[Write] ボタンをクリックした時に起動されるプログラムが CfdWriterFoam.py で、この中で 118行目、

TemplateBuilder.TemplateBuilder(self.case folder, self.template path, self.settings)

によって解析実行用のケースファイルが作成されている。ここに、 self.case folder が出力先フォルダ、self.template path がテンプレートケース(デフォルトでは、 FreeCAD/Mod/CfdOF/data/defaults )であり、 self.settings に様々な設定条件パラメタが収納されるという仕組みである。本 CfdWriter-Foam.py では、計算実行に必要な全パラメタセットを対象に一括してテンプレートケースを書き換えることになるが、この TemplateBuilder は汎用的に使えるようになっているので、特定ファイル中の特定のパラメタだけを対象にして、この構文を使って書き換えることもできるという点を強調しておきたい。

判明項目12

テンプレートファイルを書き換える仕組みの基本は、テンプレートファイル中 %( と %) で括られたパラメタを setting の Dict ファイルを使って書き換えるというものである。単なる置き換えだけでなく、 %{ や、 %: を使って、簡単な if 構文的な書き換えもできるようになっている。

判明項目12

残差グラフ表示は、 [Analysis control] タスク画面で、 Solver[Run] ボタンをクリックした時に起動される CfdRunnableFoam.py の(89 行目 )get solver cmd が起動され、この中で (92 行目 )

self.residualPlot = ResidualPlot()

として、 CfdRedisualPlot.py の ResidualPlot() が起動される。

判明項目13

ResidualPlot() は、 QtCore.QTimer() オブジェクトで、 self.Timer.start(2000) として、 2 秒毎に更新( self.refresh )されるようになっている。その他、グラフ軸の表示方法( Plot モジュールの設定)などはここで実施している。

判明項目14

残差データそのものは、 TaskPanelCfdControl.py 中( 55 行目)

self.solver run process = CfdConsoleProcess(finishedHook=self.solverFinished,
std-outHook=self.gotOutputLines, stderrHook=self.gotErrorLines)

として、 self.gotOutputLines にストアされた計算ログ出力が CfdRunnableFoam.py の( 102 行目)
process output(self, text): に渡されて、ログの解析を実施した後、( 138 行目) updateResidual されるようになっているので、これを CfdRedisualPlot.py の (43 行目 )def updateResiduals(self, residuals):
で受けて、 self.update フラグが True に更新されるので、残差グラフの更新も実施されという仕組みで
ある。

判明項目15

CFD Mesh タスク画面において [Write mesh case] ボタンを押すと、 184 行目の writeMesh() 関数が実行され、

208 FreeCADGui.doCommand("cart_mesh.setupMeshCaseDir()")
209 self.consoleMessage("Exporting mesh refinement data ...")
210 FreeCADGui.doCommand("cart_mesh.processRefinements()") # Writes stls so need file structure
211 FreeCADGui.doCommand("cart_mesh.processDimension()")
212 FreeCADGui.doCommand("cart_mesh.writeMeshCase()")

208 行目でメッシュ作成用ケースフォルダを作成、 212 行目にて CfdMeshTools.py の writeMesh-
Case() 関数により、ファイルの実体が書き換えられる事になるが、ここでも最終的に、 718 行目の
TemplateBuilder が使用されている。

TemplateBuilder.TemplateBuilder(self.meshCaseDir, self.template path, self.settings)
判明項目16

CFD Mesh タスク画面において [Run mesher] ボタンを押すと、 228 行目の runMesh() 関数が実行され、上記 writeMeshCase() 関数により作成された Allmesh コマンドを使って、以下のようにして、コマンドを実行し、コンソール出力している。

235 cmd = CfdTools.makeRunCommand(’./Allmesh’, cart_mesh.meshCaseDir, source_env=False)
236 FreeCAD.Console.PrintMessage("Executing: " + ’ ’.join(cmd) + "\n")

前へ 目次 次へ

DEXCSランチャー v2.5 製作メモ / 2. CdfOFとは



CfdOF は OpenFOAM のフロントエンドとして機能させるべく、 FreeCAD のワークベンチモジュールと
して開発中のもので、 https://github.com/jaheyns/CfdOF に公開されているものである(図 3 )。

図 3 CfdOF (イメージは開発元の HP より転用)

また最近になって、使用方法を解説した日本語記事も見られるようになったので、以下に記しておく。

2.1 CfdOF の使用方法概要

図 4 において、CfdOF ワークベンチを選択すると、 CfdOF ツールバーが現れるので、これを使って、
に示すような様々なコンテナを作成していくものである。図 5 には、図 4 におけるそれぞれのコンテナと
ツールボタンの対応を取り纏めておくが、解析に必要な機能が凡そ網羅されていることが確認できよう。それ
ぞれのツールボタンを押すとコンテナが作成され、そのコンテナ上で様々な選択メニューを使って FreeCAD
のコンポーネントに対応付けて解析パラメタを設定できるようになっている。当然であるが、作成されたコン
テナをダブルクリックして設定変更も可能である。

図 4 CfdOF の使用方法イメージ
図 5 CfdOF の主要コンテナ

2.2 CfdOF の特徴と使用感

(注)評価は2021年5月時点のもので、本記事の公開時点(2021年7月)では更新されたものになっており、その内容については未評価である。

ざっと使ってみただけの使用感であるが、ソルバー選択(図 6 )や流体の選択メニュー(図 7 )に見られる
ように、商用ソフト的な使い方を目指したソフトと思われた。残念ながら現時点ではソルバー対応が不十分、
メッシュの詳細適合が困難などあって、限定的な用途でしか使えないと考えられた。特に後者で cfMesh の領
域細分化機能を使えないのが致命的であった。

図 6 ソルバー選択タスク画面
図 7 流体特性選択タスク画面

一方、フレーム全体としては、 FEM ワークベンチと類似であり、次節に示すようにコード内容も比較的容
易に理解できるものであったので、 DEXCS ランチャーの新プラットフォームとして、本ワークベンチを使え
そうな感触は得られた。

2.3 DEXCS ワークベンチ / ランチャー化へ向けての着眼点・方針

DEXCS-OF の GUI 化コンセプトは、商用ソフトのそれとは異なり、 OpenFOAM 本来の設定ファイルを
ブラックボックス化するものではなく、あくまで設定ファイルの変更や編集の手助けをするツールとして位置
づけるものである。
したがって、 CfdOF のコンテナの中で、

  • ソルバー選択
  • 流体特性
  • 初期条件
  • 境界条件

等のコンテナについてまで流用しようとするものでなく、これらは現行 DEXCS ランチャーの機能で十分と
考えている。
一方、現行 DEXCS のメッシュ作成マクロについては、改良したい課題もあるので、 CfdOF のコンテナの

  • メッシュ作成ケース
  • メッシュ細分化設定

を使って、現行 Wiget で実施出来ている機能(+改良予定項目)が実現出来るべく、現行 CfdOF/ メッシュ
細分化設定コンテナのプロパティを拡張できないか?という考え方である。
また、

  • ソルバー実行ケース

コンテナについては、現行 DEXCS ランチャーの機能でも十分ではあるが、残差プロット表示は見た目にも
DEXCS のそれよりも美しい。これは Plot ワークベンチを使っているという説明であったが、あわよくばこ
れを使って現行 DEXCS の jgp を代用できる可能性もありそうな感触を得た。
そこで現行 CfdOF のコードについて、メッシュ作成とソルバー実行⇒残差グラフ表示の仕組みあたりを中
心に、まずはどういう仕組みでプログラムが成り立ち、動いているのか調べてみた。

前へ 目次 次へ

DEXCSランチャー v2.5 製作メモ/ 1. はじめに



DEXCS ランチャーは、図 1 に示すような開発経緯を経て、 v2 ( DEXCS2019 )以降の現在は FreeCAD を
プラットフォームとして起動することで、解析対象を見ながら設定が可能となり、それなりの使い勝手が向上
したと考えている。

図 1 DEXCS ランチャー開発経緯

一方、解析に際して肝となるのがメッシュ作成であり、 v1.5 ( DEXCS2014 )ではこれを従来の snappy-
HexMesh から cfMesh に変更することで、設定も作成も容易になった。とは云うもの、 cfMesh のフルオプ
ションを手軽に設定できるまでには至っていないので、これを少しずつ改良して現在に至っているが、依然と
していくつかの問題が残されている。たとえば、

  • スケール変換機能の組み込み
  • meshDict インポート不具合対応
  • オプションパラメタの GUI 化
  • テンプレートケースの変更設定
  • maxCellSize のロジック変更
  • OF 端末起動

といったあたりである。
それぞれの具体的な課題は認識されており、個々の対応もさほど難しいものではないが、これを現在の
Widget 上で実現するのは困難になってきた(図 2 )。


図 2 メッシュ作成マクロ( Widget )の変遷

そこで、これまでの設定方法をこの Widget の手直しでなく、 DEXCS ワークベンチともいえるような新た
なフレーム上で再構築できないと考えた。とはいえこれをスクラッチで作成出来る能力はないので、既存のフ
レームを改変して実現できないかと考えた。既存のフレーム(ワークベンチ)を調査したところ、 CfdOF と
いうワークベンチが候補として浮上した。

目次 次へ 

DEXCSランチャー v2.5 製作メモ

(2021/5/15)のオープンCAE勉強会@関西にて、表題構想の与太話をさせていただきましたが、これがようやく形になりつつあり、やりたい事の50%程度は出来上がって、順調にいけば、次のDEXCS2021でリリースできそうな目処がついてきました。今回は製作メモを作成しながらの開発中で、この際これも公開する事としました。一応、以下の目次にて執筆予定(2021/7/6現在、3-5までは執筆済み 2021/7/23現在、3-7までは執筆済み 2021/8/11現在、4-2までは執筆済み)で、HTML版が完成した部分には、ハイパーリンクで内容を閲覧できるようにしていく予定です。



  1. はじめに
  2. CfdOF とは
    1. CfdOF の使用方法概要
    2. CfdOF の特徴と使用感
    3. DEXCS ワークベンチ / ランチャー化へ向けての着眼点・方針
    4. CfdOF のソースコードと主要プログラムの動作メカニズム
  3. DEXCS ワークベンチ / CfdOFのGUIを使ってDEXCSマクロを動かす
    1. 残差プロット 1
    2. 残差プロット 2
    3. その他の変更
    4. CfdOF ⇒ dexcsCfdOF 改変の基本方針
    5. メッシュ作成方法(細分化指定無し)の変更(DEXCS化) 1
    6. メッシュ作成方法(細分化指定有り)の変更(DEXCS化)2
    7. 中間まとめ
  4. DEXCSワークベンチ / CfdOFのGUIを改変
    1. メッシュ作成タスク画面の改変
    2. メッシュ細分化タスク画面の改変その1
    3. メッシュ細分化タスク画面の改変その2
    4. FreeCAD基本形状を使った細分化領域指定
    5. まとめ
  5. Plot ワークベンチを使った post Processing処理
    1. 単グラフの自動作成
    2. ポスト処理イメージと実装方針

以下、公開にあたって、執筆理由、動機、狙い、下心、、、など記しておきます。

今回の製作は、コードハッキングして作っているようなもので、ハッキング対象がかなり大きなプログラムなので、自分の年老いた小さな前頭葉には全貌が収まりそうになく、少し間を空けてしまうと、何をやったのか、何をやろうとしていたのかをほとんど忘れてしまいます。

そこで今回は、表題の製作メモを作成しながら開発することとなった訳です。

メモもどういう形式で残したものか、これまでTex⇒PDFにて作成、読み返しながら文書を組み替えたりやってきて、3-5まで書き終わった段階でページ数も30ページを超える分量となってしまっています。そうなると、アレは何処に書いたっけ?と読み返すのが結構面倒な作業になります。紙に印刷してあれば、パラ読みで探すのはさほど難しい事ではないけれど、書き掛け中の文書を一々印刷したりはしないのが普通です。ここはやはり文書のあちらこちら、参考資料を含めてハイパーリンクで辿れるようになっていないと、コード開発にも文書作成にも生産性が上がりません。

そこで残りは慣れ親しんだHTMLで(というか拙宅ブログ記事として)書こう!となったんですが、せっかくHTMLで書くのなら、これも公開しない理由は無いという事です。公開するメリットとして、

  • 本職プログラマやユーザーから建設的なコメントをもらえるかもしれない
  • DEXCS本第2弾につながるかもしれない

など、あわよくばでしかありませんが、公開しなければ、これら可能性を完全に閉ざしてしまう事になってしまうというか、、、まぁ自己満足でしかないかも。