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

4. DEXCSワークベンチ / CfdOFのGUIを改変

メッシュ作成に関して、オリジナルのCfdOFでは、cfMesh だけでなく、snappyHexMesh, gmsh にも対応できるフレームになっているが、DEXCSランチャーでは、このフレームは残す(将来的にcfMesh以外も使えるようにする)が、当面はcfMeshを作成するとして、現行DEXCSランチャーに対する不足分と、機能追加予定分を実装していくこととする。



なお、cfMesh作成用のパラメタとして、globalパラメタとlocalパラメタがあるので、前者はメッシュコンテナ、後者はメッシュ細分化コンテナ上で設定変更できるようにするのが常識的なアプローチであろう。

4-1. メッシュコンテナの改変

図34. メッシュコンテナの改変イメージ

メッシュコンテナの改変イメージを図に示す。赤枠部が追加されており、具体的には、

  1. Feature Angle
    • STLファイルをfmsファイルへ変換する際の、特徴(輪郭線)抽出角度
  2. Scale to Meter
    • FreeCAD上のモデルサイズ(通常はミリメートル)をメートルに変換する際の係数
  3. KeepCellsIntersectingBoundary
  4. optimeizeLayer
    • レイヤーの最適化オプション(6つ)
  5. workFlowControl
    • (デバッグ用)メッシュ作成ステップを途中で止める

である。現行のDEXCSマクロと比較すると、このうち、2番目が新設、4番目については詳細パラメタの設定変更が、5番目についても任意の段階が選択可能になるという事である。

(1) GUI画面作成部分の変更

メッシュコンテナ上のGUIパーツ(文字や、ボタン、テキスト入力欄など)を、Qtのwidget, frame にどうやってレイアウトするかの情報は、dexcsTaskPanelCfdMesh.ui というファイルにまとめて記述されている(これそのものは多分、GUIツールで自動作成されたものである)。この内容は、実際に生成されるGUI画面とコードを対比しながら眺めれば容易に理解できる(図35)。

図35. メッシュ作成タスク画面と、その生成コード

したがって、手作業による改変はさほど難しくはない。図36.に改変例を示しておく。なお、実際に追加したコードはスクラッチで記述したものではなく、類似のパラメタブロックをコピーして貼り付け。名前など必要部分のみ手修正するというやり方で実施できている。

図36. 改変(追加)の具体例

この画面情報(dexcsTaskPanelCfdMesh.ui)は、_dexcsTaskPanelCfdMesh.pyが起動されると、def __init__()において、

self.form = FreeCADGui.PySideUic.loadUi(os.path.join(os.path.dirname(__file__), "dexcsTaskPanelCfdMesh.ui"))

として読み込まれ、その少し下で、ボタンや編集可能アイテムがクリックされた時のイベントが割り付けられているので、追加したボタンやチェックボックス、リストセレクションに関しては、以下朱字部分を追加。

self.form.pb_write_mesh.clicked.connect(self.writeMesh)
self.form.pb_edit_mesh.clicked.connect(self.editMesh)
self.form.pb_run_mesh.clicked.connect(self.runMesh)
self.form.pb_stop_mesh.clicked.connect(self.killMeshProcess)
self.form.pb_paraview.clicked.connect(self.openParaview)
self.form.pb_load_mesh.clicked.connect(self.pbLoadMeshClicked)
self.form.pb_clear_mesh.clicked.connect(self.pbClearMeshClicked)
self.form.pb_searchPointInMesh.clicked.connect(self.searchPointInMesh)
self.form.pb_stop_mesh.setEnabled(False)
self.form.pb_paraview.setEnabled(False)
self.form.snappySpecificProperties.setVisible(False)
self.form.optimizer_frame.setVisible(False)
self.form.check_reCalculateNormals.setChecked(True)

self.form.cb_dimension.addItems(_CfdMesh.known_element_dimensions)
self.form.cb_utility.addItems(_CfdMesh.known_mesh_utility)
self.form.cb_workflowControls.addItems(_CfdMesh.known_workflowControls)

self.form.if_max.setToolTip("Enter 0 to use default value")
self.form.pb_searchPointInMesh.setToolTip("Specify below a point vector inside of the mesh or press 'Search' "
                                                  "to try to automatically find a point")
self.form.if_cellsbetweenlevels.setToolTip("Number of cells between each of level of refinement")
self.form.if_edgerefine.setToolTip("Number of refinement levels for all edges")

self.form.check_optimiseLayer.stateChanged.connect(self.updateUI)

また、def_updateUI()での更新において、

if self.form.check_optimiseLayer.isChecked():
    self.form.optimizer_frame.setVisible(True)
else:
    self.form.optimizer_frame.setVisible(False)

を追加した。

以上で、新規にメッシュコンテナを作成した場合の初期画面を作り直すことができた。

(2) コンテナプロパティの追加

編集可能アイテムに関しては、そのプロパティを定義する必要がある。これらプロパティは、CfdMesh.py中の、 def initProperties(…) のブロックで定義されているので、既に定義済のパラメタの記述方法を参考にして、以下追加した。

addObjectProperty(obj, "FeatureAngle", 30, "App::PropertyFloat", "Mesh Parameters",
                  "Feature Angle of STL parts")
addObjectProperty(obj, "ScaleToMeter", 1, "App::PropertyFloat", "Mesh Parameters",
                  "Scale Factor to meter")
addObjectProperty(obj, "keepCellsIntersectingBoundary", False, "App::PropertyBool", "Mesh Parameters",
                  "activates smoothing of boundary layers")
addObjectProperty(obj, "optimiseLayer", False, "App::PropertyBool", "Mesh Parameters",
                  "keep template cells intersecting boundary")
addObjectProperty(obj, "opt_nSmoothNormals", 3, "App::PropertyInteger", "Mesh Parameters",
                  "number of iterations in the procedure for reducing normal variation")
addObjectProperty(obj, "opt_maxNumIterations", 5, "App::PropertyInteger", "Mesh Parameters",
                  "maximum number of iterations of the whole procedure")
addObjectProperty(obj, "opt_featureSizeFactor", 0.4, "App::PropertyFloat", "Mesh Parameters",
                  "ratio between the maximum layer thickness and the estimated feature size")
addObjectProperty(obj, "opt_reCalculateNormals", True, "App::PropertyBool", "Mesh Parameters",
                  "activale 1 or deactivate 0 calculation of normal")
addObjectProperty(obj, "opt_relThicknessTol", 0.01, "App::PropertyFloat", "Mesh Parameters",
                  "maximum allowed thickness variation of thickness between two neighbouring points, devided by the distance between the points")
addObjectProperty(obj, "workflowControls", _CfdMesh.known_workflowControls, "App::PropertyEnumeration",
                     "Mesh Parameters", "workflowControls")

但し、これだけでは、ここで追加したプロパティとメッシュ作成タスク画面に表示される変数との関連付けが出来ていない。これには、_dexcsTaskPanelCfdMesh.py中の、def __load__(self) と、def __store__(self)を使っている。つまり、メッシュ作成コンテナをダブルクリックすると、 def __load__(self)に従って、プロパティの値がメッシュ作成タスク画面のパラメタ値に反映され、メッシュ作成タスク画面を閉じると、その時点での設定値が、def __store__(self)に従ってプロパティの値として収納されるという仕組みになっている。

したがって、def __load__(self) 中に、以下追加。

self.form.if_featureAngle.setValue(self.mesh_obj.FeatureAngle) 
self.form.if_scaleToMeter.setValue(self.mesh_obj.ScaleToMeter) 
self.form.check_keepCells.setChecked(self.mesh_obj.keepCellsIntersectingBoundary) 
self.form.check_optimiseLayer.setChecked(self.mesh_obj.optimiseLayer) 
self.form.if_nSmoothNormals.setValue(self.mesh_obj.opt_nSmoothNormals) 
self.form.if_maxNumIterations.setValue(self.mesh_obj.opt_maxNumIterations) 
self.form.if_featureSizeFactor.setValue(self.mesh_obj.opt_featureSizeFactor) 
self.form.check_reCalculateNormals.setChecked(self.mesh_obj.opt_reCalculateNormals) 
self.form.if_relThicknessTol.setValue(self.mesh_obj.opt_relThicknessTol) 
index_utility = self.form.cb_workflowControls.findText(self.mesh_obj.MeshUtility)
self.form.cb_workflowControls.setCurrentIndex(index_utility)

def __store__(self)中に、以下追加

FreeCADGui.doCommand("\nFreeCAD.ActiveDocument.{}.FeatureAngle "
                     "= {}".format(self.mesh_obj.Name, self.form.if_featureAngle.value()))
FreeCADGui.doCommand("\nFreeCAD.ActiveDocument.{}.ScaleToMeter "
                     "= {}".format(self.mesh_obj.Name, self.form.if_scaleToMeter.value()))
FreeCADGui.doCommand("\nFreeCAD.ActiveDocument.{}.keepCellsIntersectingBoundary "
                     "= {}".format(self.mesh_obj.Name, self.form.check_keepCells.isChecked()))
FreeCADGui.doCommand("\nFreeCAD.ActiveDocument.{}.optimiseLayer "
                     "= {}".format(self.mesh_obj.Name, self.form.check_optimiseLayer.isChecked()))
FreeCADGui.doCommand("\nFreeCAD.ActiveDocument.{}.opt_nSmoothNormals "
                     "= {}".format(self.mesh_obj.Name, self.form.if_nSmoothNormals.value()))
FreeCADGui.doCommand("\nFreeCAD.ActiveDocument.{}.opt_maxNumIterations "
                     "= {}".format(self.mesh_obj.Name, self.form.if_maxNumIterations.value()))
FreeCADGui.doCommand("\nFreeCAD.ActiveDocument.{}.opt_featureSizeFactor "
                     "= {}".format(self.mesh_obj.Name, self.form.if_featureSizeFactor.value()))
FreeCADGui.doCommand("\nFreeCAD.ActiveDocument.{}.opt_reCalculateNormals "
                     "= {}".format(self.mesh_obj.Name, self.form.check_reCalculateNormals.isChecked()))
FreeCADGui.doCommand("\nFreeCAD.ActiveDocument.{}.opt_relThicknessTol "
                     "= {}".format(self.mesh_obj.Name, self.form.if_relThicknessTol.value()))
FreeCADGui.doCommand("FreeCAD.ActiveDocument.{}.workflowControls "
                     "= '{}'".format(self.mesh_obj.Name, self.form.cb_workflowControls.currentText()))

することにより、コンポーネントツリー上で、CfdMeshコンテナを選択した際、プロパティ画面の中に追加したパラメタセットとその値が表示されるで、メッシュ作成タスク画面での設定値と整合していることを確認しながら上記コードを修正した。もちろんここでも、類似のコードブロックをコピーして貼り付け。名前など必要部分のみ手修正するというやり方で実施できている。

以上で、追加したグローバルパラメタをモデルプロパティとして参照できるようになったので、meshDict作成プログラムに反映(改変)する。

(3) meshDict作成プログラムの変更

追加したグローバルパラメタを改めて以下に取り纏めておく。

  1. Feature Angle
    • STLファイルをfmsファイルへ変換する際の、特徴(輪郭線)抽出角度
  2. Scale to Meter
    • FreeCAD上のモデルサイズ(通常はミリメートル)をメートルに変換する際の係数
  3. KeepCellsIntersectingBoundary
  4. optimeizeLayer
    • レイヤーの最適化オプション(6つ)
  5. workFlowControl
    • (デバッグ用)メッシュ作成ステップを途中で止める

meshDictファイルの書き換えというのは、厳密には、3番面以降の項目について実施することになる。dexcsCfdMeshTools.py の def meshDict(…) において、meshDictファイルをほとんどベタ書きしているだけなので、

(3-1)FeatureAngle

dexcsCfdMeshTools.py の def perform(…) において

command = command + MainControl.SPACE_STR + self.viewControl.get_featureAngleValue()

としていたのを、3-5節では暫定的に

command = command + MainControl.SPACE_STR + " 30 "

と変更していた部分である。これを、

_featureAngle = self.mesh_obj.FeatureAngle
command = command + MainControl.SPACE_STR + " " + str(_featureAngle)

と変更すれば良いことになる。ここに、self.mesh_obj.FeatureAngle として、プロパティの値を取得しているが、対象となるオブジェクトself.mesh_objは、3-5-(4)で得られた知見を使って、class MainControl() の def __init__(self) において、

for obj in FreeCAD.ActiveDocument.Objects:
    if hasattr(obj, "Proxy") and isinstance(obj.Proxy, _CfdMesh):
       self.mesh_obj = obj

として取得するようにした。こうしておけば、他の関数ブロック内でも参照できるようになるので、併せて、3-5-(4)で記したメッシュ基本サイズ(CharacteristicLengthMax)の取得方法も、上記を参照して利用するよう変更した。

(3-2) ScaleToMeter

モデルサイズのスケール変更は、OpenFOAMの transformPoints コマンドを使って、出来上がったメッシュデータのサイズを変更する方法もあるが、これだとParaview上でメッシュデータとstlファイルとの直接比較ができなくなってしまう。stlファイルそのもののスケール変更は、cfMeshのsurfaceTransformPoints コマンドを使って実施できるので、(3-1)がclass MainControl():の冒頭で定義した

SURFACE_FEATURE_EDGES = "surfaceFeatureEdges -angle"

として、surfaceFeatureEdges コマンドを実行するものであったので、これを実行する前にclass MainControl():の冒頭に同様に

SURFACE_FEATURE_TRANS = "surfaceTransformPoints -scale"

定義しておいて、最終的に、fmsファイルを作成するまでの処理を以下のように変更した。

modelName = os.path.splitext(os.path.basename(FreeCAD.ActiveDocument.FileName))[0]
self.makeStlFile(CaseFilePath)
### step2 ### convert stl to fms file ##############################
self.fmsFileName = CaseFilePath + modelName + ".fms"
_ScaleToMeter = MainControl.SPACE_STR + str(self.mesh_obj.ScaleToMeter)
_featureAngle = MainControl.SPACE_STR + str(self.mesh_obj.FeatureAngle)
command = '. ' + MainControl.BASHRC_PATH_4_OPENFOAM + ";" + MainControl.SURFACE_FEATURE_TRANS
command = command + MainControl.SPACE_STR + "'(" + _ScaleToMeter + _ScaleToMeter + _ScaleToMeter + ")'"
command = command + MainControl.SPACE_STR + self.stlFileName + MainControl.SPACE_STR + self.stlFileName + ";"
command = command + MainControl.SURFACE_FEATURE_EDGES
command = command + _featureAngle              
command = command + MainControl.SPACE_STR + self.stlFileName + MainControl.SPACE_STR
command = command + self.fmsFileName
os.system(command)

と変更した(オリジナルのDEXCSマクロと比べると、朱字部分が追加・変更されたことになる)。もう1点重要なのは、ベースメッシュサイズもあわせて変更する必要のある点である。これは、def makeMeshDict(…) 中、以下のように変更すれば良かった(朱字部を追加)。

testDict_maxCellSize = self.mesh_obj.CharacteristicLengthMax * self.mesh_obj.ScaleToMeter

(3-3) keepCellsIntersectingBoundary

testDict_keepCellsIntersectingBoundaryCHKOption = self.mesh_obj.keepCellsIntersectingBoundary

(3-4) optimiseLayer

optimiseLayer オプションについては、使用するかどうかのチェックボックスを含めて、パラメタが6つあるので、これらを以下のように取得しておいて、

testDict_optimiseLayerCHKOption = self.mesh_obj.optimiseLayer
testDict_opt_nSmoothNormals= str(self.mesh_obj.opt_nSmoothNormals)
testDict_opt_maxNumIterations= str(self.mesh_obj.opt_maxNumIterations)
testDict_opt_featureSizeFactor= str(self.mesh_obj.opt_featureSizeFactor)
if self.mesh_obj.opt_reCalculateNormals==1:
    testDict_opt_reCalculateNormalsCHKOption = "1"
else:
    testDict_opt_reCalculateNormalsCHKOption = "0"
testDict_opt_relThicknessTol= str(self.mesh_obj.opt_relThicknessTol)

strings2 = [… を定義するブロック中、ベタ書きしていた緑字部分をコメントアウトして、朱字にて置き換える

'\t// activates smoothing of boundary layers (optional)\n' , 
'\t// deactivated by default \n' ,
#'\t// optimiseLayer		1; // \n' 
optimiseLayerString , 
'\t\n',
'\toptimisationParameters \n' 
'\t{\n'
'  \t\t// number of iterations in the procedure\n'
'  \t\t// for reducing normal variation (optional)\n'
#'  \t\tnSmoothNormals\t3;\n'
'  \t\tnSmoothNormals\t' + testDict_opt_nSmoothNormals + ';\n'
'\t\n'
'  \t\t// maximum number of iterations\n'
'  \t\t// of the whole procedure (optional)\n'
#'  \t\tmaxNumIterations\t5;\n'
'  \t\tmaxNumIterations\t' + testDict_opt_maxNumIterations + ';\n'
'\t\n'
'  \t\t// ratio between the maximum layer thickness\n'
'  \t\t// and the estimated feature size (optional)\n'
#'  \t\tfeatureSizeFactor\t0.4;\n'
'  \t\tfeatureSizeFactor\t' + testDict_opt_featureSizeFactor + ';\n'
'\t\n'
'  \t\t// activale 1 or deactivate 0 calculation of normal\n'
'  \t\t// (optional)\n'
#'  \t\treCalculateNormals\t1;\n'
'  \t\treCalculateNormals\t' + testDict_opt_reCalculateNormalsCHKOption + ';\n'
'\t\n'
'  \t\t// maximum allowed thickness variation of thickness\n'
'  \t\t// between two neighbouring points, devided by\n'
'  \t\t// the distance between the points (optional)\n'
#'  \t\trelThicknessTol\t0.01;\n'
'  \t\trelThicknessTol\t' + testDict_opt_relThicknessTol + ';\n'

(3-5) workflowControls

workflowControls についても、以下のようにstopAfterStringsを定義して、

if self.mesh_obj.workflowControls == 'none':
    stopAfterString = '\t//\tstopAfter\tedgeExtraction;\n'
else:
    stopAfterString = '\t\tstopAfter\t' + self.mesh_obj.workflowControls +';\n'

strings8 = [… のセクションにおいて、そのまま使えば良い。

'workflowControls\n',
'{\n',
'\t//\t1.templateGeneration\n',
'\t//\t2.surfaceTopology\n',
'\t//\t3.surfaceProjection\n',
'\t//\t4.patchAssignment\n',
'\t//\t5.edgeExtraction\n',
'\t//\t6.boundaryLayerGeneration\n',
'\t//\t7.meshOptimisation\n',
'\t//\t8.boundaryLayerRefinement\n',
'\n',
#'\t//\tstopAfter\tedgeExtraction;\n',
stopAfterString ,
'\n',

前へ 目次 次へ

Share

コメントする

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

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