ParaViewはさまざまな入力フォーマットに対応しているが、リーダの性能にかなりばらつきがあり、一部機能が利用できない、時刻情報付きで非定常データが読み込めない、表示が不安定になるなどの不具合が一部リーダにおいて確認されている。現状では、動作が安定しているEnSightリーダを介してデータを読み込み、ParaView標準のVTK Multi-block Dataset形式でデータを保存後、再度読み込むというステップを推奨している。
しかし、EnSight Case形式のデータをVTK Multi-block Dataset形式で保存すると、ブロック名および時刻情報(非定常データの場合)が失われる。これらの情報を手作業で修復することは困難であるが、本スクリプトを適用すれば、出力後の*.vtmファイルを修正し、欠損した情報を復元することができる。
本スクリプトを使用する前に、EnSight Case形式のデータを読み込み、File→Save DataからVTK Multi-block Dataset(*.vtm)形式で元データと同じディレクトリに保存しておく。このとき、ファイル名(拡張子を除く)は元データと同じでなければならない。また、データ保存時のData Modeオプションはアスキーエンコーディングとする。さらに、非定常データの場合は‘Write all timesteps as file-series’をチェックしておく。
ParaViewを一旦リセットないし再起動し、EnSight Case形式の元データを読み込んだ状態で本スクリプトを実行する。定常データの場合は、ブロック名を付与した*.vtmファイルが新たに生成される。非定常データの場合は、ブロック名を付与した*.vtmファイルと時刻情報を付与した*.pvdファイルが新たに生成される。
動作確認環境
ParaView 3.14.1 64bit、CentOS 6.2 64bit、Python 2.7.3
Script
optimizeVTM.py
import xml.etree.ElementTree as ET
import os
import os.path
suffix = "_org"
def indent(elem, level = 0):
i = "\n" + level * "\t"
if len(elem):
if not elem.text or not elem.text.strip():
elem.text = i + "\t"
if not elem.tail or not elem.tail.strip():
elem.tail = i
for elem in elem:
indent(elem, level + 1)
if not elem.tail or not elem.tail.strip():
elem.tail = i
else:
if level and (not elem.tail or not elem.tail.strip()):
elem.tail = i
activesource = GetSources()[GetSources().keys()[0]]
activesourceinfo = activesource.GetDataInformation().GetCompositeDataInformation()
vtkFileName = activesource.CaseFileName.split("/")[-1].split(".")
vtkFilePath = activesource.CaseFileName[:-len(vtkFileName[1]) - 1]
def exportVTM(allstep, step):
if allstep < 1:
vtkOldFileName = vtkFilePath
else:
vtkOldFileName = vtkFilePath + "_" + str(step)
if os.path.isfile(vtkOldFileName + ".vtm"):
os.rename(vtkOldFileName + ".vtm", vtkOldFileName + suffix + ".vtm")
vtmRoot = ET.parse(vtkOldFileName + suffix + ".vtm").getroot()
list_dataset = vtmRoot.findall("vtkMultiBlockDataSet/DataSet")
for i in range(0, len(list_dataset)):
list_dataset[i].set("name", activesourceinfo.GetName(i).strip())
list_dataset[i].text = ""
vtmFile = open(vtkOldFileName + ".vtm", "w")
indent(vtmRoot)
vtmFile.writelines(ET.tostring(vtmRoot))
vtmFile.close()
list_time = activesource.TimestepValues
if len(list_time) > 1:
pvdRoot = ET.Element("VTKFile")
pvdRoot.set("type", "Collection")
pvdRoot.set("version", "0.1")
pvdRoot.set("byte_order", "LittleEndian")
pvdRoot.append(ET.Element("Collection"))
pvdCollection = pvdRoot.find("Collection")
for i in range(0, len(list_time)):
tmpElem = ET.Element("DataSet")
tmpElem.set("timestep", str(list_time[i]))
tmpElem.set("group", "")
tmpElem.set("part", "0")
tmpElem.set("file", vtkFileName[0] + "_" + str(i) + ".vtm")
pvdCollection.append(tmpElem)
exportVTM(len(list_time), i)
pvdFile = open(vtkFilePath + ".pvd", "w")
pvdFile.writelines("<?xml version=\"1.0\"?>\n")
indent(pvdRoot)
pvdFile.writelines(ET.tostring(pvdRoot))
pvdFile.close()
else:
exportVTM(0, 0)
コメントを残す