Jupyter NotebookでOpenFOAMの結果をインタラクティブに可視化した

# はじめに
Jupyter Notebookで3Dデータ(VTK)をクリクリ可視化するK3D-Jupyrerについて、概説します。

[OpenDreamKitのK3Dの紹介ページ](https://opendreamkit.org/2018/10/28/3d/)がデモページになっている。興味を覚えた方はお進みください

# 環境(サーバー)
Python 3.5.5 (anaconda)
OpenFOAM v6.0
Ubuntu 16.04.3 LTS (Xenial Xerus)

各パッケージの情報

```bash
Name: vtk
Version: 8.1.0
Summary: VTK is an open-source toolkit for 3D computer graphics, image processing, and visualization
Home-page: https://vtk.org/
Author: VTK Community
Author-email: vtk-developers@vtk.org
License: BSD
Location: /home/ubuntu/.pyenv/versions/anaconda3-5.0.1/envs/py35/lib/python3.5/site-packages
Requires: 
Required-by: pygem
---
Name: K3D
Version: 2.4.20
Summary: Jupyter notebook extension for 3D visualization.
Home-page: http://jupyter.org
Author: k3d team
Author-email: artur.trzesiok@gmail.com
License: MIT
Location: /home/ubuntu/.pyenv/versions/anaconda3-5.0.1/envs/py35/lib/python3.5/site-packages
Requires: traittypes, numpy, ipydatawidgets, traitlets, ipywidgets
Required-by: 
```

# K3D-jupyter
* [OpenDreamKit](https://opendreamkit.org/) プロジェクト内作られたパッケージ
* Jupyter NotebookのExtension
* GitHub: [https://github.com/K3D-tools/K3D-jupyter](https://github.com/K3D-tools/K3D-jupyter)
* MITライセンス

# インストール
公式通り実行。~~ただJupyter labのExtensionとしてインストールができなかった。
まだlabは使ったことがないのでインストールせず。（未解決、、、）~~
コメント頂きました。しっかり待てばJupyter labのExtensionもインストールできるようです

```bash:Terminal
pip install k3d
jupyter nbextension install --py --sys-prefix k3d
jupyter nbextension enable --py --sys-prefix k3d
jupyter labextension install k3d #　<- 時間がかかる。辛抱強く待つ
```

# Jupyter Notebookの起動
OpenFOAMの環境変数を読み込んだ状態でJupyter Notebookを起動する

```bash:Terminal
source /opt/openfoam6/etc/bashrc
nohup jupyter notebook --notebook-dir=~/ >/dev/null 2>&1 &
```

起動したJupyter Notebook Serverにアクセス。
適当な場所で新規ノートブックを作成
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132571/48159333-073a-b592-5e9d-a11d7ad1857a.png)

以降、Jupyter Notebook内で実行する

#　OpenFOAMチュートリアルの実行
1つ目のセルで下記を実行する

```bash:Notebook
%%bash
cp -r $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily ./
cd ./pitzDaily
blockMesh >log.blockMesh 2>&1
simpleFoam >log.simpleFoam 2>&1
tree -L 1
```
出力。ちゃんと計算できている

```bash:Output
.
├── 0
├── 100
├── 200
├── 288
├── constant
├── log.blockMesh
├── log.simpleFoam
├── postProcessing
└── system

7 directories, 2 files
```
# vtk処理
K3Dに必要な処理は、reader,filterのみ。
mapper,actor,render,windowはK3Dにしてもらう。

OpenFOAMの読み込み(vtkOpenFOAMReader)については
[PyQt5とvtkを使ってOpenFOAMの結果を可視化してみた](https://qiita.com/matsubaradaisuke/items/0c1eeaf587ba7676a906)を参考に、一部流用させていただく。
以下をNotebookの2つめのセルで下記を実行。

```python:Notebook
filename = "./pitzDaily/system/controlDict"

#Readerの準備
reader = vtk.vtkOpenFOAMReader()
reader.SetFileName(filename)
reader.CreateCellToPointOn()
reader.DecomposePolyhedraOn()
reader.EnableAllCellArrays()
reader.EnableAllPatchArrays()
reader.Update() #データの読み込み

tArray =vtk_to_numpy(reader.GetTimeValues())    #出力ファイルの時間を格納
reader.UpdateTimeStep(tArray[-1])               #最新の時間288を出力設定

reader.Update()#最新の時間を読み込み

rgo = reader.GetOutput()　#Readerの出力を格納(vtkMultiBlockDataSetオブジェクト)
usg = rgo.GetBlock(0)　#vtkMultiBlockDataSetの扱い難しいのでvtkUnstructuredGridを取り出し

gf = vtk.vtkGeometryFilter() 
gf.SetInputData(usg)　#
gf.Update()　#GeometoryFilterの読み込み
```
# K3Dで可視化
いよいよ可視化。色が必要ならcolor_attributeのオプション引数が必要。
必要であれば、流線,断面,ベクトルなど複数のvtkデータを用意してplotに追加(+=)してあげる

```python:Notebook
import k3d

# plotの準備
plot = k3d.plot()

# データの準備
pitzDaily = k3d.vtk_poly_data(gf.GetOutput(), 
                              color_attribute=('p', -10, 10), 
                              color_map=k3d.colormaps.paraview_color_maps.Warm_to_Cool)
# データをplotに追加
plot += pitzDaily
# 表示
plot.display()
```

出力結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132571/f1270731-088f-8983-2483-6766940fcb6d.png)

尚、GUIのマウス操作は下記の通り
* 左ドラッグで回転
* ホイールでズーム
* 右ドラッグでパン

描写領域の右上にあるControlsは以下のの機能が便利(抜粋)

* Controls
    + Screenshot: 現在の絵をpngにしてダウンロード
    + Snapshot: 可視化データを埋め込んだHTMLファイルをダウンロード。  
    (完全にオフラインで利用する場合はHTML内のJavaScriptもダウンロードしてHTMLファイルを書き換えればOK)
    + Detach widget: 別ウィンド表示。ウィンドウを閉じればNotebookに戻る
    + Full screen: フルスクリーン。Escで戻る
    + lighting: 明るさは見やすさ
    + Clipping planes: クリッピングができる。  
    (k3d.vtk_poly_dataの描写データはサーフェイス化されているのか、内部が中空。。。)
* Objects -> Mesh #?
    + wireframe: ワイヤーフレーム表示。メッシュサイズによっては近づかないとわからない
    + vmin,vmax: 色表示の上下限
    + visible: 表示、非表示の切り替え

特に、Snapshotが秀逸。解析結果の配布、閲覧に使える