はじめに
DEXCS2023では、プロットツールについても諸々改良中である。ここに備忘録として取りまとめておく。
Table of Contents
背景
プロットツールは、実際の業務においては、かなり使用頻度が高いもので、DEXCS2022を使った自身の業務で何度も使用することが多かったが、プロットデータが長大になると、データ処理時間がかかるのが難点であった。特に、DEXCS2021まで搭載していたJGPと比較して、その差は歴然であったので、DEXCS2023では、DEXCS2023の作り方の記事で記したようにJGPを復活させている。
一方、DEXCSプロットツールにおいても、処理時間そのものの高速化は(plotワークベンチの仕事なので)無理にしても、プロットデータ数を間引き処理などして実用上困らないツールへの改変は可能と考え、これに取り組むこととした。
また、もう1点、実際の業務において、DEXCSランチャーをプラットフォームとして実行する場合もあるが、TreeFoamをプラットフォームとして使う場合も多い。その際にDEXCSプロットツールを使えないのも残念であった。これも使えるようにしたかった。
プロットデータ数を削減する方法
プロットデータの数を削減するには、大きく2つの方法が考えられた。すなわち、
- データを間引いて表示する
- 一部のデータだけを表示する
前者は、計算時間全体での傾向を把握したい場合の表示方法である。後者については表示区間をどう設定するのか、方法はいくつか考えられたが、現実的には計算中の最新データを見れるようにしておけば十分であろう。
そこで、データ数の削減パラメタとして、以下設定できるようにした。
プロット数制限方法−1
FreeCADの❶「編集」から❷「設定」メニューを選択、現れた「設定」画面において、❸「dexcsCfdOF」の設定メニューの最下段で❹プロット制限のパラメタを指定、変更できるようにした。ここで指定した値がデフォルト値になる。
プロット数制限方法−2
但し、このパラメタは、解析ケースに応じて用途が異なる場合も大いに有り得た。そこで、❶解析コンテナに新たにプロパティ(「Plot Maxnumber」と「Plot Method Last」)を追加し、これらをケース毎に変更できるようにした。起動時デフォルトでは、前項で指定した値が組み込まれているが、❷「100000」⇒❸「50」と変更して❹プロットツールを起動、❻「plot」ボタンを押せば、最新50個のデータがプロットされ、「Plot Method Last」を❽「false」にて❾「plot」ボタンを押せば、❿間引きされたデータがプロットされるという仕組みである。
なおここで、本来であれば、「Plot Method Last」に対する選択を「true」または「false」とするのでなく、前項の設定に合わせて「Plot Method」に対する選択として「Last」または「Decimate」としたかったが、プログラミングの手間が面倒なのでこうしただけで、自分の余裕もしくは強いニーズがあれば変更したい気持ちのある点は付け加えておく。
プログラミングの観点でも試行錯誤したので、要所について備忘録として残しておく。
dexcsPlotPost.py
from dexcsCfdAnalysis import _CfdAnalysis
for obj in FreeCAD.ActiveDocument.Objects:
if hasattr(obj, 'Proxy') and isinstance(obj.Proxy, _CfdAnalysis):
if obj.IsActiveAnalysis:
maxN = int(obj.PlotMaxnumber)
maxmethod = obj.PlotMethodLast
if maxmethod :
maxMethod = 0
else :
maxMethod = 1
上記は、dexcsPlotPost.py中、163行目以降の内容で、前項で説明した解析コンテナのプロット制限パラメタを読み取っている箇所である。ここで読み取ったmaxN とmaxMethod を使って、プロットデータを抽出するのに、以下のように、
PlotValue = self.process_column(Y_File[k], Y_column[k], Y_scaleFactor[k],maxN,maxMethod)
PostsY[Y_Legend[k]] = PlotValue
関数preocess_column に渡す引数パラメタを追加した。
def process_column(self,plotFile,columnNumber,scaleFactor,maxN,maxMethod):
f = open(plotFile,"r")
text = f.readlines()
f.close()
listN = len(text)
if listN > maxN :
if maxMethod == 1:
numStart = 0
numDiv = listN // maxN
else :
numStart = listN - maxN
numDiv = 1
else :
numStart = 0
numDiv = 1
postV = []
#for line in text:
for num in range(numStart, listN, numDiv):
split = text[num].split()
if split[0] != "#" :
try:
postV.append( float((split[columnNumber].replace('(','')).replace(')','')) * scaleFactor )
except:
pass
return postV
19行目のforループで、開始位置(numStart)と増分値(numDiv)を指定できるようにしたもので、7〜16行目で、設定したパラメタに基づいて、これらの値(numStart, numDiv)を計算している。
なお、この7〜16行目の処理は、他の関数ブロック(process_column_X, process_column_vector)でも全く同じ処理であるので、本来であればこの部分を関数化して使いたいところであるが、これも手間が面倒でそのままになっている。
TreeFoamから使えるようにしたい
DEXCS2022では、プロットツールを起動するにはDEXCSランチャーから起動するしか無かったが、実際の業務ではDEXCSランチャーを使わないで済ませられるケースも多々あり、その場合には、TreeFoamを使うので、TreeFoamから起動できるようにすべく、「十徳メニュー」を拡張した。
DEXCSプロットツールの起動方法
十徳ナイフメニューの❸「DEXCSプロットツールの起動」から、確認ダイヤログにて❹「OK」ボタンを押すと、❺解析コンテナだけのFreeCADが立ち上がるとともに、DEXCSプロットツールが立ち上がるので、.dpltファイルが存在すれば、選択して❼プロットすることができる。存在しなければ空欄になるだけで、❽「新規」ボタンを押してTable_GUIを立ち上げることも可能(但し、postProcessingファイルが存在することが前提)。
十徳ナイフメニューのプログラム実体は、/opt/DEXCS/SWAL/pyDexcsSwak.py にあり、以下の関数ブロックを追加し、これを起動できるようtreeFoam本体(/opt/TreeFoam/treefoam.py)も改造した(この改造法については、ソースコード中、十徳ナイフ用改造箇所に取りまとめられているので省略、)。
/opt/DEXCS/SWAK/pyDexcsSwak.py
def runPlotTool(caseDir, envOF):
DexcsSwakCommand = _("DEXCSプロットツール")
title = DexcsSwakCommand
msg = DexcsSwakCommand + _("を実行します")
os.chdir(caseDir)
if checkOpenFoamFileSystem(caseDir) :
cmd = "freecad /opt/DEXCS/SWAK/runDexcsPlotTool.py " + caseDir
runCommand(msg, title, cmd)
else:
ErrorDialog(DexcsSwakCommand + _("\nを実行できませんでした"))
要所は7行目で、以下のpythonスクリプトを第1引数として、ケースファイルを第2引数として、freecadを立ち上げているだけである。
/opt/DEXCS/SWAK/runDexcsPlotTool.py
import FreeCAD
import dexcsCfdAnalysis
import dexcsCfdTools
import dexcsCfdRunPlotTool
import sys
args = sys.argv
caseDir = args[2]
App.newDocument()
analysis = dexcsCfdAnalysis.makeCfdAnalysis('dexcsCfdAnalysis')
dexcsCfdTools.setActiveAnalysis(analysis)
Gui.Selection.addSelection('Unnamed','dexcsCfdAnalysis')
FreeCAD.getDocument('Unnamed').getObject('dexcsCfdAnalysis').OutputPath = caseDir
Gui.runCommand('Cfd_RunPlotTool',0)
このスクリプトは、FreeCADでプロットツールを起動するまでの操作をマクロとして記録し、その内容を編集し直したものである。