追記
2017-03-26 追記 --- pvbatchの並列実行
可視化対象
今回は適当にキャビティ流れを対象とします.
tutorials/incompressible/icoFoam/cavity
実行
blockMesh icoFoam
可視化をするソースコード
とりあえず実行
OpenFOAMの可視化はpvpython
を使って行います.
以下のファイルを適当に保存して,
pvbatch filename.py
とかで実行してみましょう するとaniフォルダが生成されて,連番のpngが生成されているはずです. それを適当に結合すると下の実行結果みたいな感じになります(writeInterbalをいじっているのでちょっと細かく出てます.)
from paraview.simple import * cavity_OpenFOAM = PV4FoamReader( FileName='./cavity.OpenFOAM' ) cavity_OpenFOAM.UiRefresh = 0 cavity_OpenFOAM.VolumeFields = ['p', 'U'] cavity_OpenFOAM.MeshParts = ['internalMesh'] RenderView1 = GetRenderView() RenderView1.CenterAxesVisibility = 0 RenderView1.OrientationAxesVisibility = 0 RenderView1.Background = [1.0, 1.0, 1.0] DataRepresentation6 = Show() DataRepresentation6.EdgeColor = [0.0, 0.0, 0.5000076295109483] DataRepresentation6.SelectionPointFieldDataArrayName = 'p' DataRepresentation6.SelectionCellFieldDataArrayName = 'p' DataRepresentation6.ScalarOpacityUnitDistance = 0.01924175606617764 DataRepresentation6.ExtractedBlockIndex = 2 DataRepresentation6.ScaleFactor = 0.010000000149011612 RenderView1.CameraClippingRange = [0.2611983736150351, 0.2905205542589584] DataRepresentation6.ScalarOpacityFunction = [] DataRepresentation6.ColorArrayName = ('CELL_DATA', 'U') DataRepresentation6.ColorAttributeType = 'CELL_DATA' a3_U_PVLookupTable = GetLookupTableForArray( "U", 3, RGBPoints=[0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0] ) at = AnnotateTime() annotateShow = Show(at) annotateShow.Color = [0.0,0.0,0.0] view = GetActiveView() size0 = view.ViewSize view.ViewSize = [1024, 768] l = servermanager.rendering.ScalarBarWidgetRepresentation() l.LookupTable = a3_U_PVLookupTable l.Title = 'U' l.Enabled = 0 l.TitleFontSize = 12 l.LabelFontSize = 10 l.LabelColor = [0.0,0.0,0.0] l.TitleColor = [0.0,0.0,0.0] l.AutomaticLabelFormat = 0 l.LabelFormat = '%1.1f' view.Representations.append(l) AnimationScene1 = GetAnimationScene() AnimationScene1.EndTime = 0.5 AnimationScene1.PlayMode = 'Snap To TimeSteps' import commands import os if not os.path.exists("./ani"): os.mkdir("./ani") times = map(float, commands.getoutput("foamListTimes").split("\n")) for time in times: AnimationScene1.AnimationTime = time Render() WriteImage('./ani/U'+str('%.04f' % time)+'.png')
output
解説
このコードは1から書いたものではありません. Paraviewで生成されたものをどうにかするとこんな感じになります.
Paraviewでおおまかなソースコードの作成
- paraFoamを起動する
- cavity.OpenFOAMをDeleteする
- [MenuBar]->[Tools]->[Start Trace]を起動する
- cavity.OpenFOAMを再び読み込む(MenuBar->File->Recent Filesから読み込むと早いです)
- Uの可視化を行う.
- [MenuBar]->[Tools]->[Stop Trace]を押す
今こんな感じだと思います. 2番目はPipeline Borwserの[☓ Delete]を押すって意味です意味不明だとお思いますが,これをすると後が楽です.
で,同時にScript Editorからなんか出てくると思います. そのスクリプトを回すと今回起きた内容を再現できます.
簡易的なソースコードの解説といろいろ付け足し
これをベースにいろいろ付け加えていくと,上記のソースコードのようになるのですが,一部わかっておいたほうがいいものがあるので少し解説します
caseの読み込み
cavity_OpenFOAM = PV4FoamReader( FileName='./cavity.OpenFOAM' )
軸の非表示,背景色変更
RenderView1 = GetRenderView() RenderView1.CenterAxesVisibility = 0 RenderView1.OrientationAxesVisibility = 0 RenderView1.Background = [1.0, 1.0, 1.0]
AnnotateTime追加
at = AnnotateTime() annotateShow = Show(at) annotateShow.Color = [0.0,0.0,0.0]
出力画像サイズの変更
view = GetActiveView() size0 = view.ViewSize view.ViewSize = [1024, 768]
色の設定,range設定
Blue -> Redの例 [min, r, g,b, max, r, g, b]の順
a3_U_PVLookupTable = GetLookupTableForArray( "U", 3, RGBPoints=[0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0] )
ScalarBar(右についてるカラーバー)の表示,設定
LookupTableはGetLookupTableForArrayで受け取ったものを表示する
l = servermanager.rendering.ScalarBarWidgetRepresentation() l.LookupTable = a3_U_PVLookupTable l.Title = 'U' l.Enabled = 0 l.TitleFontSize = 12 l.LabelFontSize = 10 l.LabelColor = [0.0,0.0,0.0] l.TitleColor = [0.0,0.0,0.0] l.AutomaticLabelFormat = 0 l.LabelFormat = '%1.1f' view.Representations.append(l)
カメラの座標の設定
カメラの座標はparaviewの3Dの右にあるカメラボタンを押せば,現在の情報が表示されます. xmlで吐くこともできるので,それを読み取るとスムーズです
view = GetActiveView() view.CameraViewUp = [0, 1, 0] view.CameraFocalPoint = [0.25, 0.0199999995529652, -0.00499999988824129] view.CameraViewAngle = 45 view.CameraPosition = [0.25,0.0199999995529652 , 0.224204409914699]
時間ステップの変更,再描画
commands moduledで外部コマンドであるfoamListTimesを呼び,描く時間ステップを取得
AnimationTimeを設定し,Render()
WriteImage()
を呼ぶことで,描く時間を取得し,animationを出力することができます.
最終的にこの連番pngをimagemagickなりffmpegなりで動画化すれば,動くようになります.
AnimationScene1 = GetAnimationScene() AnimationScene1.EndTime = 0.5 AnimationScene1.PlayMode = 'Snap To TimeSteps' import commands import os if not os.path.exists("./ani"): os.mkdir("./ani") times = map(float, commands.getoutput("foamListTimes").split("\n")) for time in times: AnimationScene1.AnimationTime = time Render() WriteImage('./ani/U'+str('%.04f' % time)+'.png')
References
[Paraview] Slices generation with pvpython
PENGUINITIS - ParaView Python Script によるポスト処理
ParaView’s Python documentation! — ParaView/Python 5.4.1-766-g40689f7 documentation
(2017-03-26追記) pvbatchの並列実行
mpirun -np n pvbatch filename.py
で並列実行できるらしいです
pvbatchで描画せずに画像だけ表示
pvbatch --use-offscreen-rendering filename.py
http://www.opencae.or.jp/wp-content/uploads/2015/06/course20111201handout.pdf