LoginSignup
12
9

More than 5 years have passed since last update.

PyQt5とvtkを使ってOpenFOAMの結果を可視化してみた

Last updated at Posted at 2018-01-22

はじめに

pyqt5上でOpenFOAMの計算結果をvtkで表示する方法を簡単にまとめます。
ほぼ、私向けの備忘録となってます。

環境

OS: windows7
OpenFOAM v4.0
python 3.6.4
pyqt5-5.9.2
vtk-8.0.0
numpy

ファイル構成

case/
 ├ pyvtk.py (本プログラム)
 └ pitzDaily
    ├ 0 (中身はp,Uなど)
    ├ constant
    ├ system
    ├ 100 (以下フォルダ0と同様)
    ├ 200
    ├ 300
    ├ 400
    └ 406
↓github
https://github.com/matsubaraDaisuke/my_qiita/tree/master/pyvtk

簡単な説明

vtkライブラリには「vtkOpenFOAMReader」クラスが標準で実装されており、簡単にOpenFOAMの結果を読み込むことができる。
VTKの使い方の流れは、以下の様な流れで使用する。
Reader→Filter→Mapper→Actor→Renderer→Window
詳しくはVTK勉強会資料が役につ(↓pdfの表示)
http://www.simulation-studies.org/wp-content/uploads/2014/01/vtk_semi_comp.pdf

vtkを使ったOpenFOAMの結果の読み込み

#!/usr/bin/env python

# -*- coding: utf-8 -*-
import os
import vtk as vtk
import numpy as np
from vtk.util.numpy_support import vtk_to_numpy

rootDir = "pitzDaily"
fileName = rootDir + "/system/controlDict"

# reader
reader = vtk.vtkOpenFOAMReader()
reader.SetFileName(fileName)
reader.CreateCellToPointOn()
reader.DecomposePolyhedraOn()
reader.EnableAllCellArrays()
reader.Update()

tArray =vtk_to_numpy(reader.GetTimeValues())    #出力ファイルの時間を格納
print(tArray)                                   #output-> [   0.  100.  200.  300.  400.  406.]
reader.UpdateTimeStep(tArray[-1])               #最新の時間406を出力設定
reader.Update()

filter = vtk.vtkGeometryFilter()
filter.SetInputConnection(reader.GetOutputPort()) #filterにreaderを設定


# mapper
mapper = vtk.vtkCompositePolyDataMapper2()
mapper.SetInputConnection(filter.GetOutputPort()) #mapperにfilterを設定
##スカラー値の設定
mapper.SetScalarModeToUseCellFieldData() #scalarデータ用に設定
mapper.SelectColorArray("p")             #圧力を表示する
mapper.SetScalarRange(-10,50)            #圧力を[-10,50]の範囲で表示

# actor
actor = vtk.vtkActor()
actor.SetMapper(mapper)             #actorにmapperを設定

# renderer
renderer = vtk.vtkRenderer()
renderer.AddActor(actor)            #rendererにactorを設定

##背景色の設定
renderer.GradientBackgroundOn()      #グラデーション背景を設定
renderer.SetBackground2(0.2,0.4,0.6) #上面の色
renderer.SetBackground(1,1,1)        #下面の色

#Window
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(renderer)         #Windowにrendererを設定

iren = vtk.vtkRenderWindowInteractor();
iren.SetRenderWindow(renWin);

renWin.SetSize(850, 850)
renWin.Render()
iren.Start();

結果

拡大や回転もできる。
result.png

pyqt5とvtkを使ったOpenFOAMの結果の読み込み

#!/usr/bin/env python

# -*- coding: utf-8 -*-
import sys
import os
import vtk as vtk
import numpy as np
from vtk.util.numpy_support import vtk_to_numpy

from PyQt5 import QtCore, QtGui
from PyQt5 import Qt
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

class MainWindow(Qt.QMainWindow):

    def __init__(self, parent = None):
        Qt.QMainWindow.__init__(self, parent)

        #Qtの枠の設定
        #########追加
        self.setWindowTitle('QtSample')

        self.frame = Qt.QFrame()
        self.vl = Qt.QVBoxLayout()
        self.iren = QVTKRenderWindowInteractor(self.frame)
        self.vl.addWidget(self.iren)
        self.frame.setLayout(self.vl)
        self.setCentralWidget(self.frame)

        #########window以外は一緒
        self.rootDir = "pitzDaily"
        self.fileName = self.rootDir + "/system/controlDict"

        # reader
        self.reader = vtk.vtkOpenFOAMReader()
        self.reader.SetFileName(self.fileName)
        self.reader.CreateCellToPointOn()
        self.reader.DecomposePolyhedraOn()
        self.reader.EnableAllCellArrays()
        self.reader.Update()

        tArray =vtk_to_numpy(self.reader.GetTimeValues())    #出力ファイルの時間を格納
        print(tArray)                                   #output-> [   0.  100.  200.  300.  400.  406.]
        self.reader.UpdateTimeStep(tArray[-1])               #最新の時間406を出力設定
        self.reader.Update()

        self.filter = vtk.vtkGeometryFilter()
        self.filter.SetInputConnection(self.reader.GetOutputPort()) #filterにreaderを設定


        # mapper
        self.mapper = vtk.vtkCompositePolyDataMapper2()
        self.mapper.SetInputConnection(self.filter.GetOutputPort()) #mapperにfilterを設定
        ##スカラー値の設定
        self.mapper.SetScalarModeToUseCellFieldData() #scalarデータ用に設定
        self.mapper.SelectColorArray("p")             #圧力を表示する
        self.mapper.SetScalarRange(-10,50)            #圧力を[-10,50]の範囲で表示

        # actor
        self.actor = vtk.vtkActor()
        self.actor.SetMapper(self.mapper)             #actorにmapperを設定

        # renderer
        self.renderer = vtk.vtkRenderer()
        self.renderer.AddActor(self.actor)            #rendererにactorを設定

        ##背景色の設定
        self.renderer.GradientBackgroundOn()      #グラデーション背景を設定
        self.renderer.SetBackground2(0.2,0.4,0.6) #上面の色
        self.renderer.SetBackground(1,1,1)        #下面の色

        #Window
        #########追加
        self.iren.GetRenderWindow().AddRenderer(self.renderer)
        self.iren.SetSize(850, 850)
        self.iren.Initialize()
        self.iren.Start();
        self.show()



if __name__ == "__main__":
    app = Qt.QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec_())

結果

枠のタイトルがPyQtのQtSampleとなっていることがわかる。
result.png

リンク

続編
PyQt5とvtkを使ってOpenFOAMの結果を可視化してみた その2(「ファイルを開く」の実装編)

不具合

macOS High Sierra v10.13.2で動作確認をしたところ以下のような不具合が発生した。枠全体に表示されずに、左下に小さく表示されてしまう。

スクリーンショット 2018-01-22 21.21.31.png

12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9