先の投稿にて、DEXCSランチャーの課題については、以下のように取り纏めてあった。
- 細部の改良
- 未実装の設定パラメタGUI化
- DEXCSプロットツールの機能拡張
- 編集⇒設定メニューの無用部削除
- DEXCS以外の環境での動作検証
- モデルだけをコピーした際の出力先問題
- snappyHexMesh対応
- FreeCADAppImage 版から起動する TreeFoamサブセットの機能不全
- FreeCADの標準ワークベンチモジュール化
- メッシュ細分化対象面の選択方法改善
現時点で、リンクを貼った項目(1-3, 6)についてはほぼ完成しており、引き続き第2番目の項目に取り掛かったが、この課題については、問題が何であるのか、もう少し掘り下げて検討する必要性があると再認識するに至った。ここに整理して取り纏めておくこととした。
なお、改訂版のソースコードは、https://gitlab.com/dexcsof/dexcs-launcher/ から取得できるようにしておいた。
承前
DEXCSランチャーを使って作成したFreeCADファイルでは、解析コンテナが作成されておりメッシュの細分化情報もモデルのプロパティとしてモデルファイル中に埋め込まれている。したがって、モデルファイル(.fcstd)だけを別の場所に「コピーまたは移動」(以下、「コピー」と略す)して、これら情報を再利用出来るという嬉しさがある。
とはいうもの、FreeCADファイルを普通にコピーしただけで、新規に解析しようとなって「ケース作成」ボタンを押しても、コピー先のtestフォルダで解析ケースファイルが作成されないという事になって、(多分)利用者の意図とは異なった状況になる(図1.)。
これは解析ケースファイルの出力先情報もそのまま引き継がれているからである。コピー先で解析ケースファイルを作成するには、この情報を変更する必要がある。(多分)と記したのは、元場所もしくは、常に同一のフォルダでケースファイルを作成したいと考える利用者はその限りでないからであり、デフォルト設定(モデルと同一場所に解析ケースファイルを作成)のままの一般利用者はコピー先で解析ケースファイルが作成されないのを見て、パニックに陥ってしまいかねない。
コピーしたモデルの解析ケースファイルの出力先(以下、「解析フォルダ」と称する)情報を手作業で変更する方法は図2.の通りであるが、これを利用者にコピーした都度そ実施させるのは何とかしたい、というのが元々の課題設定であった。そして、これだけを自動化するのであれば、さほど難しくは無いと考えていた。
問題点は何か?
図1.のユースケースを想定するだけであるならば、問題はさほど無かったのであるが、図1.以外に様々なユースケースを考えていくと、課題解決が容易とは考えられなくなってきた。具体的なユースケースの例として以下にあげておく。すなわち、
- 「編集」⇒「設定」⇒「dexcsCfdOF」において、「Default output directory」を指定してある場合
- 旧版のcfMesh作成マクロを使ってメッシュ出力先を変更した場合
- 解析コンテナが複数ある場合
などあって、これらはモデルのコピー以前の問題である。特に第3項で解析コンテナ毎に解析フォルダを変更した場合に、DEXCSツールバーのボタンを押した時、複数の解析コンテナ中のどのコンテナを対象にしてケースファイル操作をする事になるのか?など利用者は困惑するのは必至である。実際の開発の舞台裏として、かようなユースケースまでは想定していなかった、というのが正直なところである。
実は、解析コンテナで作業する際の解析フォルダ情報は、図2.に示したプロパティ情報を使っているのだが、DEXCSツールバー上で様々な(TreeFoamやそのサブセットを使う)機能を使う際の対象とする解析フォルダ情報は別物から取得している。具体的にはモデルファイル(.fcstd)の存在するフォルダ中に、.CaseFileDict という隠しファイルが存在し、この中に解析フォルダ情報が記述されているので、これを利用する仕組みとなっている。
第2,3項の操作をした場合に、解析フォルダを変更していなければ、これら2つの情報は全く同一(第1項で指定した値)になるので問題は無いが、第2,3項の操作で個別に変更した場合や、モデルファイルをコピーした時に、第1項がデフォルト値(model_dir ;モデルと同一場所)に設定してある場合に、これらパラメタ間が整合しなくなってしまう。また、モデルファイルをコピーした場合に、.CaseFileDictも併せてコピーしてあるかどうか、という状況も考えなくてはならないなど問題は複雑である。
問題複雑化の根本原因
上記のように問題が複雑になってしまった原因は、DEXCSツールバーを使用する際に、.CaseFileDict という隠しファイルを使って解析フォルダ情報を取得した事にあると思い当たった。そもそもこの仕組みは、解析コンテナを使用しない旧バージョンで利用していたものである。解析コンテナを利用して作成した解析フォルダを対象にするのであれば、解析コンテナから解析フォルダ情報を取得すべきであったが、開発当初はその取得方法がわからなくて、便宜的に解析コンテナで解析ケースを作成した際に、併せて.CaseFileDict を作成するようにしておいたものである。
ここで、DEXCSツールバー使用時に、解析コンテナから解析フォルダ情報を取得できるようになったとすれば、もう少し課題を整理できそうである。
また、解析コンテナが複数存在する場合に、複数あってもアクティブコンテナは一つだけである。したがって、解析フォルダ情報はアクティブコンテナから取得するのが真っ当なやり方であろう。操作シーンによっては、利用者にアクティブコンテナがどれであるのかを喚起させる仕組みは必要になるかもしれない。
課題の整理
そもそもの問題の原点に立ち返ると、モデルをコピーした場合に、解析フォルダ情報が変更されておらず、これを利用者が認識しないまま操作することが問題であった。そこで、FreeCADモデル(解析コンテナ付き)の「オープン処理」として、
- 解析コンテナをロード(dexcsCfdAnalysis.onDocumentRestored)した際に、アクティブコンテナの解析フォルダ情報を調べて、この値が dexcsCfdOf の設定情報と合致、もしくは.CaseFileDictが存在し、その内容と合致していれば何もしない。
- 違っていたら、そのままで良いのかどうか、確認する。変更するのであれば変更箇所を指定させ、確定値とする。
- 確定値が、dexcsCfdOf の設定情報と異なる場合には、その値を.CaseFileDictに保存する。
このようにしておけば、モデルの場所を変更した際に解析フォルダ情報の確認作業が1度必要になるだけで、2回目以降は不要になる。解析コンテナが複数あって、アクティブコンテナを変更する際にも同じ処理をする、としておけば良さそうだ。
旧版のcfMesh作成マクロを使う際には、
- 解析コンテナが存在すれば、その解析フォルダ情報を使う。
- 解析コンテナが存在しなければ、.CaseFileDictの内容に従う。
- CaseFileDictも存在しなければモデルの存在する場所
さらに旧版でcaseボタンを押して解析フォルダを変更すると、
- .CaseFileDictが書き換えられる。
- その際にアクティブコンテナが存在すれば、併せてその解析フォルダ情報も変更する。
また、DEXCSツールバーを使用する際の解析対象フォルダーの設定(確認も含む)は、
- アクティブコンテナが存在すれば、その解析フォルダ情報に従う
- アクティブコンテナが存在しなく、.CaseFileDictが存在すれば、それに従う
- .CaseFileDictも存在しない場合には、dexcsCfdOf の設定情報に従う
その他、複数のコンテナが存在し、同一解析フォルダを指定している場合に、アクティブコンテナを切り替えた時に、切り替えただけでは解析フォルダのコンテンツ(メッシュや計算結果)が作り直される訳ではないので、DEXCSツールバーでの操作対象が相応の物でなくなってしまう。これは当然の事であるが、利用者への喚起の仕組みはあった方が良いだろう。
- アクティブコンテナを切り替えた際に、解析フォルダ情報が変化するかどうか調べる
- 解析フォルダ情報が変化しない場合には、解析ケースを再構築する必要がある旨を警告する
- 解析フォルダ情報が変化する場合は、前述の「オープン処理」を実施する
という処置を追加することとする。
課題のブレークダウン
前節の課題を解決する為には、以下の要素技術を組み込む必要があった。
- アクティブ解析コンテナから解析フォルダ情報を取得する方法
- アクティブ解析コンテナの解析フォルダ情報を変更する方法
- dexcsCfdOf の設定情報を取得する方法
これらの要素技術は、これまで他のサブプログラム内で使用されてもいたのだが、新たに組み込もうとすると思い起こせないし、探すのも容易でなかった。ここで改めてコードレシピとして簡単に取り纏めておく。なお、第1,2項は、アクティブ解析コンテナを探す方法が重要な勘所であった。
アクティブ解析コンテナを探すには
from dexcsCfdAnalysis import _CfdAnalysis
for obj in FreeCAD.ActiveDocument.Objects:
if hasattr(obj, 'Proxy') and isinstance(obj.Proxy, _CfdAnalysis):
if obj.IsActiveAnalysis:
outputPath1 = obj.OutputPath
obj.OutputPath = dirName
逆に言うと、非アクティブな解析コンテナ情報については、この方法が通用しない。今の所、そういう用途は考えられないので、これ以上は考えないでおく。
dexcsCfdOfの設定情報
model = FreeCAD.ActiveDocument.FileName
prefs = dexcsCfdTools.getPreferencesLocation()
model_Dir = FreeCAD.ParamGet(prefs).GetString("DefaultOutputPath", "")
FreeCADAppImage版使用時の不具合
FreeCADモデル(解析コンテナ付き)の「オープン処理」として、変更が必要な場合にはフォルダ選択ダイアログを立ち上げて、任意のフォルダを選択できるようにしたかったが、何故かAppImage版では、フォルダ選択ダイアログが立ち上がりはするものの、その後の操作が出来なくなってしまう。今の所原因不明なので、已む無く手作業で選択してもらうよう以下のメッセージを表示することとした。
編集⇒設定メニューの無用部削除
「編集」⇒「設定」メニューから表示される「dexcsCfdOf」設定画面の、改良前後の画面イメージを以下に示しておく。
説明するまで無いと思うが、左側が従前のもので、右側が今回の改良によるものである。無用部(HISA設定など)が無くなってスッキリしたのと、日本語化も施しておいた。
GUI画面そのもの(拡張子が.uiのファイル)の変更は、Qt Designer を使って簡単に変更出来ていたのだが、この変更した画面をインポート
ui_path = os.path.join(os.path.dirname(__file__), "dexcsCfdPreferencePage.ui")
self.form = FreeCADGui.PySideUic.loadUi(ui_path)
すると、画面が真っ白になって何も表示されなくなってしまう。エラーの出所原因も表示されないので、DEXCS2021のリリースに間に合わず諦めていたもので、今回ようやく解決した。
エラーの原因は、dexcsCfdPreferencePage.ui ファイルをインポートした後に、dexcsCfdPreferencePage.ui ファイル中に定義されたパーツを引用して処理する箇所が多くあって、無用部として削除したパーツの引用箇所が存在すると、それを表示できないので画面が真っ白になるというものであった。削除したパーツの名前を調べて、その名前を足掛りにコード中の引用箇所を調べて、その行をコメントアウト(最終的には削除)して正常に動作するかどうか確認するという作業を地道に積み重ねた。
なお、日本語対応に際しては、dexcsCfdPreferencePage.ui 中での対応方法がわからなかったので、これをインポートしたプログラム本体(dexcsCfdPreferencePage.py)中で、以下のようにマルチ言語対応の表記に改めた。
self.form.label_7.setText(_("OpenFOAM install directory"))
self.form.label_7b.setText(_("ParaView executable path"))
self.form.label_outputdir.setText(_("Default output directory"))
self.form.label_5.setText(_("Template Case"))
tool_tip_mes = _("The OpenFOAM install folder (e.g. 'OpenFOAM-xxx').")
self.form.le_foam_dir.setToolTip(tool_tip_mes)
tool_tip_mes = _("The full path of the ParaView executable.")
self.form.le_paraview_path.setToolTip(tool_tip_mes)
tool_tip_mes = _("The default output directory ('model_dir' if the same of FreeCAD Model File).")
self.form.le_output_dir.setToolTip(tool_tip_mes)
tool_tip_mes = _("Template Case Folder")
self.form.le_template_case.setToolTip(tool_tip_mes)
メッシュ細分化対象面の選択方法の改善
メッシュ細分化対象面を選択する方法が、本プログラムのハック元であるCfdOFにおいて改善されていたので、これを取り込んだ。操作方法のイメージ図を改良前後で比較したものを以下に示しておく。
全体的なイメージで説明してあるので違いが判りにくいかもしれないが、図中下半面の「対象パーツ」選択方法の部分を見比べていただきたい。特に、図4の従前、パーツを選択すると、Faceリストが現れて、どれか一つを選択という、やや意味不明な操作が必要であった部分が不要になって、わかりやすくなっていると思う。
欲を言うと、図5.の改良版(右半面)において、選択リストにすべてのパーツがリストアップされてしまうのだが、領域細分化対象とできるパーツとそうでないパーツ(対象を選択した時にソリッドパーツが表示されないもの)があり、後者はリストアップされないようにしたかった。まだそこまでは出来ていない。
なお、本家CfdOFにおいて、かなり精力的に改良は進められてはいるようであるが、どうもこちらの目指す方向とは違うようだ。そもそもメッシュ対象モデルの作成方法という根本的なところのコンセプトが異なっているので、いまだ使い方(というかモデルの作り方)もよくわからない。今回のハック(CfdSelectWidget.py をdexcsCfdSelectWidget.py に変更)当たって、不要部がかなり多くあり、思いきってそれらは削除した(まだ残っているかもしれない)。コードをスリム化、見通しを良くして残りの課題(領域細分化対象リスト)に取り組みたい。