4.2. メッシュ細分化タスク画面の改変その1
CfdOFでの細分化指定方法は、相対サイズ(Relative element size)を指定するというもので、実際にDEXCSランチャーの標準モデルで使ってみたのであるが、数値の指定方法として悩ましい面が多々あった。そこで、これをDEXCS方式(セルサイズを直接指定または二分木法の細分化レベルを指定)に変更することを懸案としていたので、まずはこれを実施することとした。
変更イメージを図37.に示す。
赤枠部分で細分化指定するが、デフォルトでは、[Refinement level:]に[1]が入り、[Real cell size:] には、メッシュ作成パネルで設定した[Base element size:](基本メッシュサイズ)の1/2の値が入るようにしておく。[Real cell size:] と、[Refinement level:]のどちらも変更可能にしておき、一方を変更したら、他方の項目は相応の値に自動変更されるようになっていれば使いやすくなりそうだ。
ここで、1点注意したいのは、数値入力欄にチェックマークとmmという単位の入っているものと、そうでないものがあるという点である。後者は単純な数値入力欄で、プロパティーが、App::PropertyFloat とか、App::PropertyIntegerであり、通常の数字を扱う方法が通用するのに対して、前者はApp::PropertyLengthとなっており、長さの単位も併記して寸法を解釈するもので、参照や値をセットする際の方法が異なってくるという点である。ここでは、便宜的にCfdOfオリジナルの[Refinement level:]相当部分を、[Real cell size:] に置き換えて、入力欄を変更したので、参照や設定部の名前だけでなくメソッドも変更する必要が生じてくるという点である。最終的に[Refinement level:]相当部分で使用していた変数名”if_rellen”は、”if_cellsize”に、相応するプロパティ名RelativeLengthをCellSizeに変更したが、最初からこれを行ってしまうと、“if_rellen”に相応するプロパティを見失ってしまうことになりかねない。変数名”if_rellen”をそのまま使っていれば、相応するプロパティの参照や設定の際にエラーとなり、その箇所は明示されるので、必要な変更を実施しておいて、最終的にちゃんと動くようになってから変数名を変更したというのが改変作業の実態である。
dexcsTaskPanelCfdMeshRefinement.ui で、新たに追加した[Refinement level:]に関しては、CfdOfオリジナルの[Refinement level:]相当部分をコピーして、以下朱字部分と青字の数値入力部を変更しただけであるが、
</item>
<!-- Label (Relative element size) -->
<item row="0" column="0">
<widget class="QLabel" name="label_reflevel">
<property name="text">
<string>Refinement level:</string>
</property>
</widget>
</item>
<!-- value (Relative element size) -->
<item row="0" column="1">
<widget class="QDoubleSpinBox" name="if_reflevel">
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
[Real cell size:] 部分は、CfdOfオリジナルの[Refinement level:]部分を直接以下のように変更した。
<!-- Label (Relative element size) -->
<item row="1" column="0">
<widget class="QLabel" name="label_cellsize">
<property name="text">
<string>Real cell size:</string>
</property>
</widget>
</item>
<!-- value (Relative element size) -->
<item row="1" column="1">
<widget class="Gui::InputField" name="if_cellsize">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string extracomment="Select 0 to use default value"/>
</property>
<property name="text">
<string>0.0</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="singleStep" stdset="0">
<double>0.010000000000000</double>
</property>
<property name="maximum" stdset="0">
<double>1000000000.000000000000000</double>
</property>
<property name="unit" stdset="0">
<string notr="true">mm</string>
</property>
<property name="format" stdset="0">
<string>2</string>
</property>
</widget>
青字部分は、App::PropertyLength用に使われる入力欄を作成するwidgetで、類似のものをブロック毎コピーして、数値部分をカスタマイズしただけである。
一方、これら入力欄に相応するコンテナプロパティは、CfdMeshRefinement.py の def initProperties(…) において、
# Common to all
#addObjectProperty(obj, "RelativeLength", 0.75, "App::PropertyFloat", "",
# "Set relative length of the elements for this region")
addObjectProperty(obj, "CellSize", "0 m", "App::PropertyLength", "",
"Set cell size for selected object(s)")
addObjectProperty(obj, "RefinementLevel", 1, "App::PropertyInteger", "",
"Set refinement level for for selected object(s)")
定義されるので、オリジナルの緑字の部分をコメントアウトして、その下に、App::PropertyLengthに変更したもの(CellSize)を追加したのと、“if_reflevel“に相応するもの(RefinementLevel)を追加した。
メッシュ細分化タスク画面の起動は、_dexcsTaskPanelCfdMeshRefinement.py が動くので、その def __init__(…)を経てdef load(self)が起動されるようになっているので、def load(self): が起動する前に、
self.baseMeshSize = Units.Quantity(self.mesh_obj.CharacteristicLengthMax).Value
if self.obj.CellSize == 0 :
self.obj.CellSize = self.baseMeshSize * 0.5
self.load()
self.form.if_reflevel.valueChanged.connect(self.changeCellSize)
self.form.if_cellsize.valueChanged.connect(self.changeBaseCellSize)
としておけば、メッシュコンテナ中の、CharacteristicLengthMax(基本メッシュサイズ)を取得して、デフォルトで(Cellsize==0で、何も指定がなかった場合には)その半分(RefLevel=1相当)の値をCellsizeプロパティに設定したことになる。また、self.load()が終わった後の2行は、メッシュ細分化タスク画面上の数値欄の値が変化した時の処置を定義したもので、以下の内容を新設した。
つまり、if_reflevelの値が変化したら、baseMeshSizeとf_reflevelの値を使って、セルサイズを計算し直す。
def changeCellSize(self):
setQuantity(self.form.if_cellsize, self.baseMeshSize/2**(self.form.if_reflevel.value()))
return True
if_cellsizeの値が変化したら、その値とif_reflevelの値を使って、CharacteristicLengthMaxを計算し直す。
def changeBaseCellSize(self):
cellLength = getQuantity(self.form.if_cellsize)
cellLength = re.findall("\d+\.\d+", str(cellLength))[0]
self.mesh_obj.CharacteristicLengthMax = float(cellLength) * 2**(self.form.if_reflevel.value())
return True
コンテナプロパティとメッシュ細分化タスク画面に表示される変数との関連付は、def load(self):
self.form.if_reflevel.setValue(self.obj.RefinementLevel)
setQuantity(self.form.if_cellsize, self.obj.CellSize)
にてコンテナ⇒タスク画面、
def accept(self)にて、
FreeCADGui.doCommand("FreeCAD.ActiveDocument.{}.CellSize "
"= '{}'".format(self.obj.Name, getQuantity(self.form.if_cellsize)))
FreeCADGui.doCommand("FreeCAD.ActiveDocument.{}.RefinementLevel "
"= {}".format(self.obj.Name, self.form.if_reflevel.value()))
タスク画面から、コンテナへ収納されるようになっている。
以上で、細分化指定方法を改良することが出来た、しかしこのままでは、CfdOFのオリジナルパラメタを流用していたcfMeshのmeshDictを作成するプログラム(dexcsCfdMeshTools.py)が動かなくなってしまう。つまり、CfdOFでは、RelativeLengthというパラメタがあって、この値をベースに細分化レベルを計算し直していた。今回の改変で、RefinementLevelという細分化レベルそのものの値をパラメタ化したので、これを使うようにするということである。
これは、たとえば、3-6-(2)において、暫定的に
RefStr = str(int( 1.0 / __relativeLength__[regionNumber])-1)
としていた部分を、以下のように変更、
RefStr = str(__reflevel__[regionNumber])-1)
併せて、__relativeLength__としてあった箇所を__reflevel__に変更するとともに、モデルコンテナからパラメタ取得していた部分、たとえば、
__relativeLength__.append(obj.RelativeLength)
を、以下のように変更するだけであった。
__reflevel__.append(obj.RefinementLevel)
複数ヶ所存在するが、ほとんど機械的な作業であった。