DEXCSランチャー v2.5 製作メモ / 解析・雛形ケースの設定



課題の背景

これまでFreeCADモデルの存在するディレクトリが解析ケースフォルダであるとして様々なツールを作成・動作確認してきた。また最初にFreeCADモデルの存在するディレクトリがケースファイルでない場合には、DEXCSの標準チュートリアル問題の設定ファイル(/opt/DEXCS/template/dexcs)を雛形ファイルとしてケースファイルを作成していた。

最終的に、解析ケースフォルダと、雛形ケースファイルは任意に変更できるようにしたいと考えるのが普通であろう。従来のDEXCSマクロにおいては、解析ケースフォルダを変更する機能は有していたが、雛形ケースファイルを選択変更する機能はなかったので、特定のケースファイル内へ出力するという使い方で対処してきており、実質的な使い方の上で大きな違いはないが、内部仕様を知らない人から見た上での解り易さが大きく違うので、ここでは雛形ケースファイルを変更する機能も実装したい。

少し余談になるが、この雛形ケースファイルを変更するメニューが出来たとして、将来的な拡張機能として、TreeFoamの「newCaseの作成」メニュー援用して、ここで選んだケースを採用する方法が考えられるが、一通りの機能が実装できた後の課題としたい。

現状確認

コンボビューにおいて、解析コンテナ(dexcsCfdAnalysis)を選択すると、プロパティ欄に[Output Path]が表示されている。

この表示テキスト欄右端のボタンを押すと、フォルダ選択ダイヤログが現れて、任意のフォルダを選択できる。この選択は有効で、以下メッシュ作成〜ソルバー実行は指定したフォルダで実行してくれる事は確認できている。但し、このワークベンチ上での操作に限定されるもので、DEXCSツールボタンによる操作には反映されす、エラーになってしまう(のは現段階では仕方無い)。

一方、「編集」⇒「設定」画面において[CfdOF]を選択すると、以下の設定画面が現れる。

ここに、[Default output directory]とあり、これも同様に変更することができるようになっている。しかしながら、ここで変更したとしても、先のプロパティには反映されない。

以上の状況から、課題は以下のように整理される。

  1. 雛形ケースファイルを変更する方法を実装する必要がある。これには、Output directory に関する上記2つの設定欄に併記される形で、Template Case を変更できるようにしておくのが普通であろう。
  2. 解析コンテナのプロパティ欄で設定した値と、「設定画面」で設定したこれらの値を連動させる仕組みが必要。
  3. DEXCSツールボタンで、Output directory のプロパティを認識させる方法が必要。
  4. 「設定画面」をCfdOF オリジナルから、dexcsCfdOF に変更したい。機能面で本質的な問題ではないが。

以下、上述の順とは不同であるが、改造点を記しておく。

設定画面(initGui.py ⇒dexcsCfdPreferencePage.py)

initGui.py において、

from dexcsCfdPreferencePage import dexcsCfdPreferencePage
ICONS_PATH = os.path.join(dexcsCfdTools.get_module_path(), "Gui", "Resources", "icons")
QtCore.QDir.addSearchPath("icons", ICONS_PATH)
FreeCADGui.addPreferencePage(dexcsCfdPreferencePage, "dexcsCfdOF")

アイコンは、Gui/Resources/iconsフォルダ中に収納されて、CfdOFのオリジナルアイコン(preference-cfdof.png)そのものを変更するのは躊躇われたので、新たにpreference-dexcscfdof.pngを用意して収納した。

dexcsCfdPreferencePage.py においては、Template Case を変更できるようにしたいが、デフォルトはDEXCS標準チュートリアル(/opt/DEXCS/template/dexcs)としたいので、最初にグローバルパラメタとして、

DEXCS_TEMPLATE = "/opt/DEXCS/template/dexcs"

定義しておく。以下、OutputDirectoryについて記述している箇所を見つけて、その下にTemplateCaseについて同様に追加しただけである。

(103行目あたり)
self.form.tb_choose_output_dir.clicked.connect(self.chooseOutputDir)
self.form.le_output_dir.textChanged.connect(self.outputDirChanged)
self.form.tb_choose_template_case.clicked.connect(self.chooseTemplateCase)
self.form.le_template_case.setText(DEXCS_TEMPLATE)
self.form.le_template_case.textChanged.connect(self.templateCaseChanged)
(209行目あたり)
def outputDirChanged(self, text):
    self.output_dir = text

def templateCaseChanged(self, text):
    self.template_case = text

以上の変更によって、改変された設定画面を以下に示す。

なお、画面データ(dexcsCfdPreferencePage.ui)は、QtDesignerを使って、オリジナルデータ(CfdReferencePage.ui)を改変したものである。その際に、HISAなるSoftwareに関する設定項目があり、dexcsCfdOfでは使用することがないので、削除を試みたが、FreeCADの起動時にエラー表示で立ち上がらなくなってしまう。その原因解明は当面ペンディングして先へ進めることとした。

解析コンテナにおけるプロパティ追加(dexcsCfdAnalysis.py)

こちらもOutput…について記述されている箇所に続けて、Templateに係る記述に変更しただけである(朱字部)。

(54行目あたり)
model = FreeCAD.ActiveDocument.FileName
#print(model)
modelDir = os.path.dirname(model)
templateCase = "/opt/DEXCS/template/dexcs"
addObjectProperty(obj, "OutputPath", modelDir, "App::PropertyPath", "",
                  "Path to which cases are written (blank to use system default)")
addObjectProperty(obj, "TemplateCase", templateCase, "App::PropertyPath", "",
                  "Path to Template case Dir (blank to use system default)")

なお、この時点では、先の「設定」画面で設定した値との連動までは考えていない。とりあえずこの画面で変更したパラメタを使って、メッシュ作成や解析実行が、所定の動作するかどうか確認していく。

また、OutputDirectoryに関するパラメタの用語は、必ずしも統一されていない(Pathが使われていたり、小文字で始まっていたりする)が、当面、これはこれで合わせておく必要はある。

解析ケースの作成

解析ケースはメッシュ作成タスク画面(_dexcsTaskPanelCfdMsh.py)で[Write]ボタンを押すと作成される。

#cart_mesh = self.cart_mesh
self.analysis = dexcsCfdTools.getParentAnalysisObject(self.mesh_obj)
output_path = dexcsCfdTools.getOutputPath(self.analysis) + os.path.sep
template_case = dexcsCfdTools.getTemplateCase(self.analysis)
try:
    QApplication.setOverrideCursor(Qt.WaitCursor)
    FreeCADGui.doCommand("dexcsCfMesh = dexcsCfMeshTools.MainControl()")
    #FreeCADGui.doCommand("dexcsCfMesh.perform("+ "'" + cart_mesh.meshCaseDir + "'" + ")")
    FreeCADGui.doCommand("dexcsCfMesh.perform("+ "'" + output_path + "', '" + template_case + "'" + ")")       

緑字でコメントアウトした部分を、朱字に変更した。ポイントは、dexcsCfMesh(オリジナルのDEXCSマクロを改造したもの)のperform()関数にてケースファイルを作成しているのであるが、これまで出力先(output_path)だけを指定していたのに対し、併せてtemplate_caseも引数に加えたという点。そして、解析コンテナにて指定したプロパティ値の取得方法である。

解析の出力先(output_case)を取得するのに、オリジナルでは、cart_mesh.meshCaseDir という形で、別途定義してある関数を使用していた。これに合わせてtemplate_caseを取得する関数を作成する事も考えられたが、その方法がよく分からなかった。そこで試行錯誤の末、ここに記した方法に辿り着いた。

解析コンテナ上のtemplate_caseを取得するのに、dexcsCfdTools.getTemplateCase(self.analysis)を使っているが、output_path を取得するdexcsCfdTools.getOutputPath(self.analysis)に倣って、dexcsCfdTools.py 中の、def getDefaultOutputPath():と、def getOutputPath(analysis):ブロックの下に、変数名が異なるだけで全く同じ手続のdef getDefaultTemplateCase(): と、def getTemplateCase(analysis):を追加した。

(75行目あたり)
DEXCS_TEMPLATE = "/opt/DEXCS/template"

def getDefaultOutputPath():
    prefs = getPreferencesLocation()
    output_path = FreeCAD.ParamGet(prefs).GetString("DefaultOutputPath", "")
    #print('output_path = ' + output_path)
    if not output_path:
        #output_path = tempfile.gettempdir()
        output_path = os.path.dirname(FreeCAD.ActiveDocument.FileName) 
    output_path = os.path.normpath(output_path)
    return output_path

def getDefaultTemplateCase():
    prefs = getPreferencesLocation()
    template_case = FreeCAD.ParamGet(prefs).GetString("DefaultTemplateCase", "")
    #print('template_case = ' + template_case)
    if not template_case:
        #template_case = tempfile.gettempdir()
        template_case = DEXCS_TEMPLATE
    template_case = os.path.normpath(template_case)
    return template_case

def getOutputPath(analysis):
    if analysis and 'OutputPath' in analysis.PropertiesList:
        output_path = analysis.OutputPath
    else:
        output_path = ""
    if not output_path:
        output_path = getDefaultOutputPath()
    output_path = os.path.normpath(output_path)
    return output_path

def getTemplateCase(analysis):
    if analysis and 'TemplateCase' in analysis.PropertiesList:
        template_case = analysis.TemplateCase
    else:
        template_case = ""
    if not template_case:
        template_case = getDefaultTemplateCase()
    template_case = os.path.normpath(template_case)
    return template_case

この変更に伴って、dexcsCfMesh(オリジナルのDEXCSマクロを改造したもの)のperform()関数の変更が必要になるが、変更はわずかで、以下朱字部を追加するだけであった。

(1601行目あたり)
def perform(self, CaseFilePath, TemplateCase):
(1648行目あたり)        
if TemplateCase:
    templateSolver =  TemplateCase
else:   
    templateSolver = self.SOLVER_PATH_TEMPLATE

以上で、解析コンテナのプロパティ値にて、解析ケース(出力先)、雛形ケースファイルを任意に設定できるようになり、メッシュ作成、解析実行できることを確認した。あとは、

  1. プレファレンスの設定画面での設定値と上記プロパティ値を連動させる
  2. DEXCSランチャーのツールボタンの動作を整合させる

プレファレンス設定画面再考

プレファレンスの設定画面での設定値と解析コンテナのプロパティ値が連動していない点が問題ではあったが、ユースケースを考えると、単に連動すれば良いというものでもなさそうだ。つまり、プレファレンスの設定画面は常時利用するものではないということである。解析コンテナで出力フォルダを変更したからといって、それが恒久的な設定になってしまうのも考えものである。そこで、解析フォルダと雛形ケースファイル(フォルダ)については、使用方法とし、以下の考え方を基本にするとした。

解析コンテナを新規作成した場合にプレファレンスの設定画面で設定したものをデフォルトとし、その設定を引き継ぐ。その後解析コンテナにて変更することは可能だが、変更したからといってプレファレンスまでは変更しない(一方向の連動のみ)。

プレファレンス設定の初期値は、user.cfg に記載されているものを使用するが、解析ケースについては、実在するディレクトリの場合にのみそれを採用する。そうでない場合には、[model_dir]が採用され、モデルの存在するディレクトリである事を示すようにする(下図参照)。

これを実現するのに、これまでオリジナルのCfdOFでは解析フォルダは特定のフォルダを使用する事を想定していた為、本改造では暫定的にInitGui.py def __init__(self) において、

prefs = dexcsCfdTools.getPreferencesLocation()
FreeCAD.ParamGet(prefs).SetString("DefaultOutputPath", "")

として、user.cfg の値に依らないで、ここでデータをクリアしていたが、この部分を元に戻した。また、プレファレンス設定画面の表示には、

(156行目あたり)
self.output_dir = dexcsCfdTools.getDefaultOutputPath()

が使われるので、

def getDefaultOutputPath():
    prefs = getPreferencesLocation()
    output_path = FreeCAD.ParamGet(prefs).GetString("DefaultOutputPath", "")
    if not output_path:
        output_path = 'model_dir'
    output_path = os.path.normpath(output_path)
    return output_path

とし、さらに解析コンテナがロードされた際に設定される出力フォルダ名を、以下のように

    def initProperties(self, obj):
        model = FreeCAD.ActiveDocument.FileName
        prefs = dexcsCfdTools.getPreferencesLocation()
        model_Dir = FreeCAD.ParamGet(prefs).GetString("DefaultOutputPath", "")
        if os.path.exists(model_Dir):
            modelDir = model_Dir
        else:
            modelDir = os.path.dirname(model)
        templateCase = FreeCAD.ParamGet(prefs).GetString("DefaultTemplateCase", "")

プレファレンス設定画面(user.cfgに記載)の表示にて指定したディレクトリが、実在するかどうかの判定をして、実在する場合にのみ採用するようにした。

DEXCSランチャーツールボタン

解析ケース(出力先)をモデルが収納されたディレクトリ以外に設定した場合に、DEXCSランチャーのツールボタンが起動しないのは、この時点ではそういう仕様であるので仕方ない。DEXCSランチャーでは、モデルが収納されたディレクトリに、.CaseFileDictを収納して、ここに出力先を記すようにしており、この時点で、このファイルが存在しないからということである。

そこで、メッシュ作成タスク画面(_dexcsTaskPanelCfdMsh.py)で[Write]ボタンを押した時に、出力先が確定した後で、以下の朱字部分を追加して、.CaseFileDict を作成するようにした。

output_path = dexcsCfdTools.getOutputPath(self.analysis) + os.path.sep

if output_path[-1] == os.path.sep:
    output_path1 = output_path[:-1] 
else:
    output_path1 = output_path
dictName = os.path.dirname(FreeCAD.ActiveDocument.FileName)  + "/.CaseFileDict"
writeDict = open(dictName , 'w')
writeDict.writelines(output_path1)
writeDict.close()

なお、出力先パス名の最後の文字がos.path.sep(パス分離記号)の場合、それを含まないようにしているのは、これが残っていると、TreeFoamが起動しなくなってしまう為であった(その他のランチャーボタンは、あってもなくても正常に起動する)。

旧版DEXCSマクロ

DEXCS2021では、旧版のDEXCSマクロも混在させた状態でリリースすることを考えているが、それとDEXCSツールバーボタンの動作を確認した。

DEXCSワークベンチによる解析コンテナを使用しない状態であれば、基本的に旧版での操作方法の通りで動作する。基本的にと記したのは、plotWatcherと、ポスト処理においてPlotモジュールが起動されるようになった点である。特にplotWatcher機能は、このボタンで使用する限り自動更新されない点は、今の所仕方無いとしておく。

一方、DEXCSワークベンチによる解析コンテナを作成した状態において、旧版DEXCSマクロを起動すると、エラーで起動できない。エラーの内容は、解析コンテナがShapeオブジェクトを有していないというものであったので、ここは、以下のように、朱字部で例外処理させることで回避できた。

            try:
                if obj.Shape:
                    if obj.Shape.BoundBox.XMax > xmax:
                        xmax = obj.Shape.BoundBox.XMax
                    if obj.Shape.BoundBox.XMin < xmin:
                        xmin = obj.Shape.BoundBox.XMin
                    if obj.Shape.BoundBox.YMax > ymax:
                        ymax = obj.Shape.BoundBox.YMax
                    if obj.Shape.BoundBox.YMin < ymin:
                        ymin = obj.Shape.BoundBox.YMin
                    if obj.Shape.BoundBox.ZMax > zmax:
                        zmax = obj.Shape.BoundBox.ZMax
                    if obj.Shape.BoundBox.ZMin < zmin:
                        zmin = obj.Shape.BoundBox.ZMin
            except AttributeError:
                pass

これにより、解析コンテナを非表示状態にしてマクロを立ち上げれば、旧版DEXCSマクロの挙動は全く同一のものになる。解析コンテナを表示状態のままマクロを立ち上げると、解析コンテナも含めてマクロ画面にリストアップされることになり、そのまま無理やりエクスポートすると、解析コンテナからastファイルが作れないとなって立ち行かなくなる。これはそういう仕様なので仕方無い。

何はともあれ、解析・雛形ケースを任意に設定可能となり、旧版DEXCSマクロや、DEXCSランチャーボタンでの動作とも整合するようにはなった(と思う)。

前へ 目次

Share

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください