くれなゐの雑記

例を上げて 自分で手を動かして学習できる入門記事を多めに書いています

pvpythonでアニメーション作成した

追記

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

f:id:kurenaif:20170227012459g:plain


解説

このコードは1から書いたものではありません. Paraviewで生成されたものをどうにかするとこんな感じになります.

Paraviewでおおまかなソースコードの作成

  1. paraFoamを起動する
  2. cavity.OpenFOAMをDeleteする
  3. [MenuBar]->[Tools]->[Start Trace]を起動する
  4. cavity.OpenFOAMを再び読み込む(MenuBar->File->Recent Filesから読み込むと早いです)
  5. Uの可視化を行う.
  6. [MenuBar]->[Tools]->[Stop Trace]を押す

今こんな感じだと思います. 2番目はPipeline Borwserの[ Delete]を押すって意味です意味不明だとお思いますが,これをすると後が楽です.

f:id:kurenaif:20170227170820p:plain

で,同時に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で吐くこともできるので,それを読み取るとスムーズです f:id:kurenaif:20171019182544p:plain

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を出力することができます. 最終的にこの連番pngimagemagickなり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