ただし空気抵抗は無視しないものとする

流体解析の勉強の題材として日頃気になったことをまとめたり確かめたりしていく予定です。OSSしか使わないつもりです。

【SALOME】スクリプトでメッシュのケーススタディ

はじめに

 以前にSALOMEを使ったヘキサメッシュの作成方法を紹介しました。

inabower.hateblo.jp

これはSALOMEのGUIを用いた方法ですが、SALOMEはTUIの中で使用すると更に便利だったりします。 今回はTUIでちょっと寸法を変えたメッシュを量産していく方法を紹介していきます。

f:id:inabower:20190406095345p:plain

お試しスクリプト

 例として以下のようなスクリプトを用意します。

sampleBox.py

# -*- coding: utf-8 -*-
import os, sys, salome, GEOM, SMESH
from salome.geom import geomBuilder
from salome.smesh import smeshBuilder

# スタディとGEOM(形状)およびSMESH(メッシュ)のオブジェクトを作成
salome.salome_init()
theStudy = salome.myStudy
geompy = geomBuilder.New(theStudy)
smesh = smeshBuilder.New(theStudy)

# 1m×1m×1mの箱を作成
Box_1 = geompy.MakeBoxDXDYDZ(1, 1, 1)
geompy.addToStudy( Box_1, 'Box_1' )

# 各面にグループ名をつける
groupNo = {'minZ':31, 'maxZ':33, 'minY':23, 'maxY':27, 'minX':3, 'maxX':13}
geomGroups = {}
for key, i in groupNo.items():
    geomGroups[key] = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
    geompy.UnionIDs(geomGroups[key], [i])
    geompy.addToStudyInFather( Box_1, geomGroups[key], key )

# メッシュを作成
Mesh_1 = smesh.Mesh(Box_1)
Regular_1D = Mesh_1.Segment()
Number_of_Segments_1 = Regular_1D.NumberOfSegments(15)
Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE)
Hexa_3D = Mesh_1.Hexahedron(algo=smeshBuilder.Hexa)
isDone = Mesh_1.Compute()

# Create groups from geometry
for key, group in geomGroups.items():
    tmp = Mesh_1.GroupOnGeom(group,key,SMESH.FACE)
    
# UNVファイルとしてエクスポート
Mesh_1.ExportUNV( 'Mesh.unv' )

 このスクリプトは1m×1m×1mの箱を作成し各辺を15分割した直方体メッシュを生成するものです。 SALOMEのGUIでFile→Load Scriptでこのファイルを読み込むと以下のようなメッシュがGUIでできていることを確認できるかと思います。 また$HOMEに"Mesh.unv"が生成されているかと思います。

f:id:inabower:20190405185048p:plain

SALOMEのTUIモード

 このスクリプトをSALOMEを起動せずに実行するにはSALOMEをインストールしたディレクトリにある"salome"ファイルに引数" -w 1 -t "を付けて以下のようにターミナルに入力します。

$ path/to/salome -w 1 -t sampleBox.py
runSalome running on inabower-LAPTOP
Searching for a free port for naming service: 2812 - OK
Searching Naming Service + found in 0.1 seconds 
Searching /Registry in Naming Service + found in 0.5 seconds 
Searching /Kernel/ModulCatalog in Naming Service +th. 140452740915712 - Trace /home/rd-ap-palmco/salome/edf/V8_4_BR/V8_4_0/modules/src/KERNEL/src/ModuleCatalog/SALOME_ModuleCatalog_Server.cxx [101] : Module Catalog Server: Naming Service was found
Warning: this type (Study,objref) already exists, it will be ignored.
Warning: this type (pyobj,objref) already exists, it will be ignored.
Warning: this type (SALOME_MED/MEDCouplingFieldDoubleCorbaInterface,objref) already exists, it will be ignored.
 found in 0.5 seconds 
RunStudy
Searching /myStudyManager in Naming Service + found in 0.5 seconds 
Searching /Containers/inabower-LAPTOP/FactoryServer in Naming Service + found in 0.5 seconds 
Start SALOME, elapsed time :   2.1 seconds
createNewStudy
extStudy 1



 ※なおAnacondaなどでデフォルトをPython3にしている場合には、Python2で書かれたSALOMEを実行することができないためPython2の環境をactivateしておく必要があります。

 これで今度はsampleScript.pyと同じ場所に"Mesh.unv"が生成されていることが確認できるかと思います。

関数によるコマンドの省略

 ただ毎回SALOMEの場所を入力するのは手間ですので~/.bashrcに関数やaliasを作成しておくと良いかと思います。

~/.bashrc

function runSalome (){
    path/to/salome -w 1 -t $1 $2
}
export -f runSalome

 Anacondaで毎回Python2にするのがしんどいという方は以下のようにすると良いかと思います。

~/.bashrc

function runSalome (){
    source activate py2 # 各自のpython2環境
    path/to/salome -w 1 -t $1 $2
    source activate base # 元の環境に戻す
}
export -f runSalome

 これで以下のコマンドで同様の実行を行うことができるようになりました。

$ runSalome sampleBox.py
runSalome running on inabower-LAPTOP
Searching for a free port for naming service: 2812 - OK
Searching Naming Service + found in 0.1 seconds 
Searching /Registry in Naming Service + found in 0.5 seconds 
Searching /Kernel/ModulCatalog in Naming Service +th. 140452740915712 - Trace /home/rd-ap-palmco/salome/edf/V8_4_BR/V8_4_0/modules/src/KERNEL/src/ModuleCatalog/SALOME_ModuleCatalog_Server.cxx [101] : Module Catalog Server: Naming Service was found
Warning: this type (Study,objref) already exists, it will be ignored.
Warning: this type (pyobj,objref) already exists, it will be ignored.
Warning: this type (SALOME_MED/MEDCouplingFieldDoubleCorbaInterface,objref) already exists, it will be ignored.
 found in 0.5 seconds 
RunStudy
Searching /myStudyManager in Naming Service + found in 0.5 seconds 
Searching /Containers/inabower-LAPTOP/FactoryServer in Naming Service + found in 0.5 seconds 
Start SALOME, elapsed time :   2.1 seconds
createNewStudy
extStudy 1



引数の追加

 このスクリプトには引数をつけることもできます。 ヘルプを見てみましょう。

$ runSalome -help
Usage: salome start [options] [STUDY_FILE] [PYTHON_FILE [args] [PYTHON_FILE [args]...]]
Python file arguments, if any, must be comma-separated (without blank characters) and prefixed by "args:" (without quotes), e.g. myscript.py args:arg1,arg2=val,...


Options:
  -t, --terminal        Launch without GUI (in the terminal mode).
  -g, --gui             Launch in GUI mode [default].
(以下略)



というわけで"args:aaa,bbb"のように引数を入力すれば良いことが分かります。 引数で箱の大きさと出力するファイル名を入力できるようにしてみます。

sampleBoxArgs.py

# -*- coding: utf-8 -*-
import os, sys, salome, GEOM, SMESH
from salome.geom import geomBuilder
from salome.smesh import smeshBuilder

# スタディとGEOM(形状)およびSMESH(メッシュ)のオブジェクトを作成
salome.salome_init()
theStudy = salome.myStudy
geompy = geomBuilder.New(theStudy)
smesh = smeshBuilder.New(theStudy)

# 引数を読み込む
print sys.argv
try:
    length = float(sys.argv[1])
    fileName = sys.argv[2]
    if not fileName.endswith('.unv'):
        raise Exception('File name must be *.unv file')
except:
    raise Exception('Wrong args')

# 1m×1m×1mの箱を作成
Box_1 = geompy.MakeBoxDXDYDZ(length,length,length)
geompy.addToStudy( Box_1, 'Box_1' )

# 各面にグループ名をつける
groupNo = {'minZ':[31], 'maxZ':[33], 'minY':[23], 'maxY':[27], 'minX':[3], 'maxX':[13]}
geomGroups = {}
for key, faces in groupNo.items():
    geomGroups[key] = geompy.CreateGroup(Box_1, geompy.ShapeType["FACE"])
    geompy.UnionIDs(geomGroups[key], faces)
    geompy.addToStudyInFather( Box_1, geomGroups[key], key )

# メッシュを作成
Mesh_1 = smesh.Mesh(Box_1)
Regular_1D = Mesh_1.Segment()
Number_of_Segments_1 = Regular_1D.NumberOfSegments(15)
Quadrangle_2D = Mesh_1.Quadrangle(algo=smeshBuilder.QUADRANGLE)
Hexa_3D = Mesh_1.Hexahedron(algo=smeshBuilder.Hexa)
isDone = Mesh_1.Compute()

# Create groups from geometry
for key, group in geomGroups.items():
    tmp = Mesh_1.GroupOnGeom(group,key,SMESH.FACE)
    
# UNVファイルとしてエクスポート
Mesh_1.ExportUNV( fileName )

 これで以下のように入力すると各辺2mの箱のメッシュが"test.unv"という名前で生成されます。

$ runSalome sampleBoxArgs.py args:2,test.unv
runSalome running on inabower-LAPTOP
Searching for a free port for naming service: 2818 - OK
Searching Naming Service + found in 0.1 seconds 
Searching /Registry in Naming Service + found in 0.5 seconds 
Searching /Kernel/ModulCatalog in Naming Service +th. 140346892026368 - Trace /home/rd-ap-palmco/salome/edf/V8_4_BR/V8_4_0/modules/src/KERNEL/src/ModuleCatalog/SALOME_ModuleCatalog_Server.cxx [101] : Module Catalog Server: Naming Service was found
Warning: this type (Study,objref) already exists, it will be ignored.
Warning: this type (pyobj,objref) already exists, it will be ignored.
Warning: this type (SALOME_MED/MEDCouplingFieldDoubleCorbaInterface,objref) already exists, it will be ignored.
 found in 0.5 seconds 
RunStudy
Searching /myStudyManager in Naming Service + found in 0.5 seconds 
Searching /Containers/inabower-LAPTOP/FactoryServer in Naming Service + found in 0.5 seconds 
Start SALOME, elapsed time :   2.2 seconds
createNewStudy
extStudy 1
['/home/inabower/Documents/Models/sampleBox/sampleBoxArgs.py', '2', 'test.unv']



 というわけでTUIでスクリプトを実行できるようになりました。

ケーススタディ

 それでは辺の長さを1m,2m,3m,4m,5mで一括メッシュ生成をしてみます。 以下のようなシェルスクリプトを作ります。

#!/bin/bash
mkdir mesh
for n in 1 2 3 4 5; do
    echo "Making mesh. Length = ${n} m"    
    runSalome sampleBoxArgs.py "args:${n},mesh/test${n}.unv"
done

これで以下のようにメッシュが一気に生成されました。

$ tree mesh
mesh
├── test1.unv
├── test2.unv
├── test3.unv
├── test4.unv
└── test5.unv

0 directories, 5 files



 なおOpenFOAMのケースを一気に作る場合は、まずorgという元となるケースを準備します。

tree org
org
├── makeMesh.sh
├── constant
└── system
    ├── controlDict
    ├── fvSchemes
    └── fvSolution

2 directories, 4 files



makeMesh.shの中身はこんな感じ。

#!/bin/bash
ideasUnvToFoam box.unv

 その上で以下のようなスクリプトでunvの変換までを一気にやります。

#!/bin/bash
mkdir mesh
for n in 1 2 3 4 5; do
    echo "Making mesh. Length = ${n} m"    
    cp -r org mesh/test${n}
    runSalome sampleBoxArgs.py "args:${n},mesh/test${n}/box.unv"
    pushd mesh/test${n}
        ./makeMesh.sh
        touch test${n}.foam
    popd
done

f:id:inabower:20190406095345p:plain

 さらにソルバーやpvbatchによる図の出力などを一括でできるようになるととても便利です。

スクリプトの作り方

 SALOMEでメッシュを作成した後にFile→Dump Studyでそれまで行った作業をスクリプトにしてくれる機能があります。 最初は「GUIで少し作業→スクリプトに吐き出す→中身を少し改造する→GUIで読み込む」を繰り返すことでスクリプトの作り方がわかってくるかと思います。 この辺りもそのうち掘り下げて説明できたらと思います。

 GUIでの作業方法は以下の記事で説明しています。

inabower.hateblo.jp

 またこんな機能無いかなと思ったら以下の公式APIを見てみましょう。

最後に

 SALOMEはとても自由度の高いメッシャですので是非試してみてください。