PyFoam メモ2013年9月21日 | |
はじめにPyFoam は、OpenFOAM をもう少し使いやすくするための Python モジュールおよびツール群である。以下では PyFoam の使い方について簡単にメモする。 バージョンOpenFOAM 2.2.1, PyFoam 0.6.1 インストールここ に従って svn でソースコードを入手。 $ svn co https://svn.code.sf.net/p/openfoam-extend/svn/trunk/Breeder/other/scripting/PyFoam/ あるいは上記ページのリンク ("Downloads" の "Current Version") からパッケージをダウンロードできる。 インストール。 $ cd PyFoam $ mkdir ~/OpenFOAM/PyFoam $ python setup.py install --prefix=~/OpenFOAM/PyFoam 以下を ~/.bashrc に追加。 export PYTHONPATH=~/OpenFOAM/PyFoam/lib/python2.7/site-packages:$PYTHONPATH export PATH=~/OpenFOAM/PyFoam/bin:$PATH 上記の "python2.7" の部分は Python のバージョンによって変わる。 Gnuplot と Python の Numpy モジュールもインストールしておく。 ~/.bashrc を読み込む。 $ . ~/.bashrc テスト以下のコマンドを実行。 $ pyFoamVersion.py OpenFOAM と PyFoam のバージョンが表示されれば OK。 また、python を立ち上げ、以下のように打ち込む。 $ python >>> import PyFoam >>> import PyFoam.FoamInformation >>> print PyFoam.FoamInformation.foamTutorials() OpenFOAM のチュートリアルのパスが表示されれば OK。 ツールpyFoamPlotRunner.pyこれを使って OpenFOAM のソルバーを実行すると、商用 CFD ソフトで見るような、残差などのグラフが表示される。 たとえば、ケースディレクトリ内で icoFoam を実行する場合は、次のようにする。 $ pyFoamPlotRunner.py icoFoam グラフのために以下のようなオプションが使える。
あとでグラフを見るには次のようにする。 $ pyFoamPlotWatcher.py PyFoamRunner.icoFoam.logfile ログファイル (ソルバーの標準出力) を指定する。上のオプションが使える。また、つぎのオプションが使える。
並列計算を行う場合は、次のようにする。 $ pyFoamPlotRunner.py --procnr=2 icoFoam --procnr で CPU 数を指定する。--autosense-parallel オプションで並列数を自動で決めるさせることもできる。 以下のようなオプションもある。
pyFoamCaseReport.pyケースの情報を表示する。ヘルプを見るには、以下のようにする。 $ pyFoamCaseReport.py -h たとえば、以下のようにすれば境界条件の情報が表示される。 $ pyFoamCaseReport.py --short-bc-report cavity また、セル数などの情報は、次のようにして得られる。 $ pyFoamCaseReport.py --case-size cavity pyFoamChangeBoundaryType.pyケースの const/polyMesh/boundary の境界のタイプを変更できる。 $ pyFoamChangeBoundaryType.py cavity movingWall patch pyFoamClearBoundaryValue.pyフィールドの境界条件の "value" の値を変更できる。 $ pyFoamClearBoundaryValue.py --value="(2 0 0)" cavity/0/U movingWall "value" 以外の値を変更したい場合はつぎのようにする。 $ pyFoamClearBoundaryValue.py --destination-key="inletValue" --value=1 0/alpha outlet pyFoamClearCase.py計算結果を削除する。改めて計算を実行しなおす場合などに使える。 $ pyFoamClearCase.py cavity 次のようにすると、並列計算用の processor* ディレクトリも一緒に削除する。 $ pyFoamClearCase.py --processors-remove cavity 最後の結果を残したい場合はつぎのようにする。 $ pyFoamClearCase.py --keep-last cavity ただし、processor* 内のデータは削除される。並列計算の結果を残したい場合は、上を実行する前に reconstructPar を実行する。 ある時間よりあとのデータだけを消したい場合はつぎのようにする。 $ pyFoamClearCase.py cavity --after=0.042 この場合、0.042 秒よりあとのデータが削除される (0.042 のディレクトリまで残る)。 pyFoamClearInternalField.pyフィールドの internalField の値を設定できる。 $ pyFoamClearInternalField.py --value="(2 0 0)" cavity/0/U pyFoamCloneCase.pyケースのクローンを作る。計算結果はコピーされない。 $ pyFoamCloneCase.py cavity cavity2 pyFoamCopyLastToFirst.pyケースの最終結果を、別のケースの初期値に設定する。 $ pyFoamCopyLastToFirst.py cavity cavity2 pyFoamCreateBoundaryPatches.pyconst/polyMesh/boundary の境界をフィールドファイルに追加する。 $ pyFoamCreateBoundaryPatches.py --verbose --overwrite --clear-unused cavity/0/U --overwrite は上書き指定、--clear-unused で使われない境界情報を削除する。つまり、よそのケースから持ってきたフィールドファイルを本ケース用に作り替える。 pyFoamDecompose.pyパラレル計算用にメッシュを分解する。 $ pyFoamDecompose.py --method=simple --n="2,1,1" --delta=1e-4 cavity 2 オプションは decomposeParDict で指定するパラメタ、最後の数字が CPU 数。decomposeParDict の用意と decomposePar の実行を勝手にやってくれる。 pyFoamListCases.pyカレントディレクトリにあるケースのリストを表示する。 pyFoamPackCase.pyケースの計算に必要なファイルだけを tar でまとめる。 $ pyFoamPackCase.py cavity "cavity.tgz" ができる。計算結果は含まない。 pyFoamReadDictionary.py辞書のキーワードの値を表示する。 $ pyFoamReadDictionary.py cavity/system/controlDict deltaT controlDict の deltaT の値が表示される。 キーワードが入れ子になっている場合は、次のようにする。 $ pyFoamReadDictionary.py cavity/system/fvSolution "PISO['nCorrectors']" pyFoamWriteDictionary.py辞書のキーワードの値を変更する。 $ pyFoamWriteDictionary.py cavity/system/controlDict deltaT 0.1 controlDict の deltaT の値が 0.1 に設定される。 キーワードが入れ子になっている場合は、次のようにする。 $ pyFoamWriteDictionary.py cavity/system/fvSolution "PISO['nCorrectors']" 3 フィールドの境界条件のタイプを設定することもできる。 $ pyFoamWriteDictionary.py 0/U 'boundaryField["wall"]["type"]' slip Python から使うPyFoam は Python モジュールであるから、Python から使ってこそ本領を発揮できるといえる。以下では PyFoam モジュールの簡単な利用例を示す。 メッシュの境界を表示する例showBoundaries.py import sys from os import path from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile if len(sys.argv) < 2: print "usage: showBoundaries.py <case>" sys.exit(0) case = sys.argv[1] try: boundary = ParsedParameterFile( path.join(case, "constant", "polyMesh", "boundary"), boundaryDict=True) except IOError, e: print "error: ", e sys.exit(-1) boundaries = boundary.content print "Case: ", case print name = True for b in boundaries: if name: print "Name: ", b name = False else: print "Type: ", b["type"] print name = True PyFoam の ParsedParameterFile を使って辞書の情報を得ている。それを使うための準備が以下の行。 from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile 辞書の情報を得ているのが以下の部分。 boundary = ParsedParameterFile( path.join(case, "constant", "polyMesh", "boundary"), boundaryDict=True) ここではケースの constant/polyMesh/boundary の情報を得ている。以下で辞書の中身を得る。 boundaries = boundary.content boundaries の要素は境界の名前と Python の辞書型データからなり、辞書型データで b["type"] などとすると、それに対応した OpenFOAM の辞書のキーワードの値にアクセスできる。 フィールドの境界を表示する例showFieldBoundaries.py
import sys
from os import path
from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile
if len(sys.argv) < 3:
print "usage: showFieldBoundaries.py <case> <field>"
sys.exit(0)
case = sys.argv[1]
field = sys.argv[2]
try:
boundary = ParsedParameterFile(path.join(case, "0", field))
except IOError, e:
print "error: ", e
sys.exit(-1)
boundaries = boundary["boundaryField"]
print "Case: ", case
print
for b in boundaries:
print "Name: ", b
print "Type: ", boundaries[b]["type"]
if boundaries[b].has_key("value"):
print "Value: ", boundaries[b]["value"]
print
はじめの constant/polyMesh/boundary にアクセスする例よりちょっぴり簡単になっている。ParsedParameterFile で ケースの 0 にあるフィールドデータを取得し、Python の辞書型データから情報を取り出している。 フィールドに境界を追加する例addFieldBoundary.py
import sys
from os import path
from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile
if len(sys.argv) < 6:
print "usage: addFieldBoundary.py <case> <field> <name> <type> <value>"
sys.exit(0)
case = sys.argv[1]
field = sys.argv[2]
name = sys.argv[3]
type = sys.argv[4]
value = sys.argv[5]
try:
boundary = ParsedParameterFile(path.join(case, "0", field))
except IOError, e:
print "error: ", e
sys.exit(-1)
boundaries = boundary["boundaryField"]
print "Case: " + case
print
print "Add boundary:"
print "Name: " + name
print "Type: " + type
if value != "":
print "Value: " + value
b = {}
b["type"] = type
if value != "":
b["value"] = "uniform " + value
boundaries[name] = b
boundary.writeFile()
print "Done."
取得した辞書情報は、取り出すばかりではなく、情報を設定することもできる。最後の boundary.writeFile() で、変更した内容をファイルに書き出している。上は境界を追加する例として示してはいるが、既存の境界を指定すれば情報を変更することができる。 | |
| PENGUINITIS | |