週末はいつも晴れ

社会人3年目の日記です。プログラミングとか旅行とかラーメン。

Rasberry Pi 3 Model B+

用途

買ったもの

Raspberry Pi 3 Model B+ スターターセット BASIC

Raspberry Pi 3 Model B+ スターターセット BASIC

Raspberry Pi用電源セット(5V 3.0A)?Pi3フル負荷検証済

Raspberry Pi用電源セット(5V 3.0A)?Pi3フル負荷検証済

既にあるもの

SSH接続できるようになるまで

qiita.com

OpenMC dockerfile

作りましたのでぜひご利用ください。
CentOS7 ベースです。

dockerfile

OpenMC dockerfile · GitHub

私の環境ではNNDCから断面積ファイルを落とすのに
2時間くらいかかりました。
海外サーバーですからね。

ファイルサイズは合計で6GBくらいになります。

コンパイルの条件

  • コンパイラ: mpif90とmpicc
  • HDF5もmpiで並列化
  • optimize有効
  • pythonはminicondaを使用してインストール
  • python関連ライブラリについては、silo以外をインストール済(Python3非対応のため)

github.com

OpenMC

日本語の情報が無いのでメモ。

The OpenMC Monte Carlo Code — OpenMC Documentation

OpenMCとは

OpenMCは粒子のモンテカルロ輸送計算コードで、臨界計算に重きを置いています。
2次曲面を含む3次元モデルのジオメトリーでシミュレーションできます。
OpenMCでは連続エネルギーと多群計算の両方をサポートしています。
連続エネルギーの粒子の相互作用データはHDF5フォーマットに基づいています。
HDF5フォーマットはMCNPやSerpentといったモンテカルロコードで使用されているACEフォーマットから生成することも可能です。

HDF5フォーマットとは
HDF5フォーマットに関するメモ書き - たまに書きます。

ACEフォーマットとか、わざわざ独自仕様にするのは本当にやめて欲しいですよね
ENDF/B形式も然りです。そろそろ現代的なものに見直そうと思わないのでしょうか?

OpenMC本体のインストール

linuxはapt-getでバイナリを落としてくることもできます。
macはソースからインストールするしかありません。
windowsは知りません。

以下はソースコードからインストールする方法

git clone https://github.com/mit-crpg/openmc.git
cd openmc
mkdir build
cd build
cmake .. # オプション指定できます
make
make install

以下はcmakeオプションのおすすめです。

cmake -DCMAKE_INSTALL_PREFIX=$HOME/.local\
      -DCMAKE_CXX_COMPILER=/usr/local/bin/g++-7\
      -Openmp=on\
      -Optimize=on ..

macxcodeで入るclangにopenmpを通すのは面倒だし、
brewでインストールしたgccを使っています。hdf5もbrewでインストールしました。
以下では上記のcmakeオプションを使用したと仮定して進めます。

インストールが完了するとCMAKE_INSTALL_PREFIXで指定したディレクトリは以下のようになります。

$ tree .local/ -L 2
.local/
├── bin
│   ├── openmc
│   ├── openmc-ace-to-hdf5
│   ├── openmc-convert-mcnp70-data
│   ├── openmc-convert-mcnp71-data
│   ├── openmc-get-jeff-data
│   ├── openmc-get-multipole-data
│   ├── openmc-get-nndc-data
│   ├── openmc-plot-mesh-tally
│   ├── openmc-track-to-vtk
│   ├── openmc-update-inputs
│   ├── openmc-update-mgxs
│   ├── openmc-validate-xml
│   └── openmc-voxel-to-silovtk
├── include
│   └── python3.5m
├── lib
│   ├── libopenmc.dylib
│   └── python3.5
└── share
    ├── doc
    ├── man
    └── openmc

9 directories, 14 files

思いっきりPythonを使うみたいですね。素晴らしい。
日本の開発はここら辺がすっごく遅いです。
私の場合は環境のPythonが使われるように設定されたようです。

断面積のダウンロード

binフォルダにあるopenmc-get-nndc-dataを使うと
ENDF/B-VII.1の断面積をNNDCからダウロードできます。

$ cd ~/.local
$ mkdir data
$ cd data
$ ~/.local/bin/openmc-get-nndc-data
Downloading ENDF-B-VII.1-neutron-293.6K.tar.gz... ^P^P^P^A^Eb 501910959  [100.00%]
Downloading ENDF-B-VII.1-tsl.tar.gz...   17925081  [100.00%]
Verifying MD5 checksums...
Extracting ENDF-B-VII.1-neutron-293.6K.tar.gz...
Extracting ENDF-B-VII.1-tsl.tar.gz...
Fixing ZAIDs for S(a,b) tables
Delete *.tar.gz files? ([y]/n) y
Converting 89225.71c (ACE) to Ac225 (HDF5)
Converting 89226.71c (ACE) to Ac226 (HDF5)
Converting 89227.71c (ACE) to Ac227 (HDF5)
〜省略〜
Converting paraD.71t (ACE) to c_para_D (HDF5)
Converting paraH.71t (ACE) to c_para_H (HDF5)
Converting sCH4.71t (ACE) to c_H_in_CH4_solid (HDF5)
Converting UUO2.71t (ACE) to c_U_in_UO2 (HDF5)
Converting ZrZrH.71t (ACE) to c_Zr_in_ZrH (HDF5)

ACEファイルがダウンロードされて、自動的にHDF5フォーマットに書き換えているようです。
私の環境ではGe76, Eu152, Mo100の変換時に怒られました。

次に断面積リストのxmlファイルcross_sections.xml環境変数に登録します。

echo "OPENMC_CROSS_SECTIONS=$HOME/.local/data/nndc_hdf5/cross_sections.xml" >> .bashrc

以上でインストールは完了です。
あとは以下のipython notebookを追えば、入門できます。
やっぱりI/O周りが素晴らしいですね
Modeling a Pin-Cell — OpenMC Documentation

MCNPのI/Oはゴミ過ぎで進歩しない。
SCALEは多少マシになったようですが、これからはPython APIが無いと若者はついて行かないです。
MCNPもAPIは無理だけど、wrapperを誰か書いてくれないものでしょうか。
あのインプットファイルとかジオメトリ可視化機能はありえない笑
ユーザーの切なる願いです。

dockerで使う方法

新らしい技術は積極的に取り入れましょう。
我々の業界は時代遅れすぎます。
「docker 使い方」とか「docker 仕組み」でググってください。

ergsさんが一番良さそうなのでお借りします。

docker pull ergs/ergs-openmc

すぐに使えるようなります。

OpenFOAMメモ

あんまりこの形式でインストールする人はいないと思います。
私用のメモ

vagrant

まずvagrantをインストールした。
イメージはCentOS7を使う。以下のVagrantFileを使用する。
Vagrant box centos/7 - Vagrant Cloud
paraviewを使うのでX11の設定を書き込む

config.ssh.forward_x11 = true

Trueにしてたせいで5分悩んだ。
コピペは積極的にすべきと再認識。

vagrantを起動

vagrant init
vagrant up

vagrantゲストのシャットダウン

vagrant halt

docker

OpenFOAMがdockerで配布されているのでdocker ceをインストールする。
vagrantssh接続してdockerをインストールした。

vagrant ssh
sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce

そのほか、X windowyumでgroupinstallした。

OpenFOAM

ここで結構めんどくさかった。

まず前提としてvagrantゲストのエディタ・ParaViewからOpenFOAMの入出力にさわりたい。
なぜならdocker上にコンパイラとかエディタを入れるのは難しいから(OpenFOAMのdockerのrootパスワードがわからない)。
また、vagrantのホストからvagrantを飛び越えてdockerのファイルにアクセスする設定をするのは面倒臭そうだから。

面倒ごとを回避しようとしても、結局面倒な問題を1つは解決しないといけない問題に衝突するんですけどね。
今回も同じ。

dockerをsudo無しで実行できるようにする

vagrantにはvagrantさんで入る。
いちいちsudoするのがめんどくさいし、sudoでdocker runしたファイルはvagarntさんがいじれなくなる。
Dockerコマンドをsudoなしで実行する方法 - Qiita

OpenFOAMをインストールする

まずはdockerのdaemonを立ち上げる

sudo systemctl start docker

OpenFOAMのdockerスクリプトをダウンロード

wget --trust-server-names https://sourceforge.net/projects/openfoamplus/files/v1706/installOpenFOAM
wget --trust-server-names https://sourceforge.net/projects/openfoamplus/files/v1706/startOpenFOAM

それぞれ実行権限を与える。

chmod +x installOpenFOAM
chmod +x startOpenFOAM

dockerのワークディレクトリをvagrantゲストのどのディレクトリに割り当てるか、installOpenFOAMのhome変数で指定する。

書きかけ

matplotlibのよくわからんところ

以下のstackoverflowの投稿の話です。
stackoverflow.com

matplotlibをググりまくっていると、上記の質問のように複数のプロット方法があることに気づくと思います。
回答はあまり質問者の意図を理解できていないようです。


これを解決しようとすると、plt.subplot()やplt.figure()が何のオブジェクトを返しているのか、そのオブジェクトのGUIグラフ上の役回りとか知る必要が出てくると思います。
1つ目の例にしても、plt.plot()って何か返してるの?とか、そのあとに何も渡していないのにplt.show()とかplt.savefig()で表示/保存されるのはなんで?matplotlibをimportした時点で何かオブジェクトが生成されてるの?とか、いろんな疑問が湧いてくると思います。

でも、こういう過去の色々を引きずってゴチャゴチャしてて、他に応用しにくそうな知識って頭に入れたくないですよね。


誰か頭のいい人がこのめんどくさい質問に回答してくれたり、解説してくれないものでしょうか

古いコードのwrapper

書きかけ


古代の計算コード(私の生まれる前に開発されたFortranコード)をpython3でwrapした経験のメモ

信頼性の観点から、新しい計算コードは認められないため(認められるためのコストが莫大になるため)、現在でも使われているコードが私の業界には多々あります。

おそらく他の業界でもよくあることでしょう。

古いコードは古い計算機で動かす前提で作成されており、並列化やパラメータサーベイ、アウトプットのポスト処理等が現状に全くマッチしません。
せっかく計算機が進歩しているのに、活用しない手は無いでしょう。

注:このポストでは古いコードのソースコードからの変更を行うものではありません。あくまでwrapperであり、実行モジュールやデータライブラリは保証・検証されているもののみを使用することを前提とします。

主に以下を達成することを目的としました。

  • インプットファイルの自動生成
  • 実行ログや日本語コメントを残せるようにすること
  • アウトプットファイルの読み込み
  • アウトプットの可視化・整理・他のアウトプットとの比較

インプットファイル

ファイルIO
入力パラメータの割り振り

実行(subprocess)

Pythonから古いコードを実行するには標準ライブラリのsubprocessを利用します。
subprocessモジュールについて私も詳細は理解できているとは言えませんが、簡単に言えばPython上で新しいコマンドプロンプトを開いて指定したシェルコマンドを実行するためのライブラリです。

主に以下のsubprocess.run()またはsubprocess.Popen()を使います:
17.5. subprocess — サブプロセス管理 — Python 3.6.1 ドキュメント
17.5. subprocess — サブプロセス管理 — Python 3.6.1 ドキュメント

単純に実行するだけならsubprocess.run()で十分です。
オリジナルの実行方法が以下であるとします。

old_program < inputfile

subprocess.run()を使用した例は以下になります。

import subprocess
cmd = 'old_program < inputfile'
subprocess.run(cmd, shell=True)

アウトプットファイル

文字列データの読み取り
数値データやcsvファイルの読み取り
バイナリ形式データの読み取り(Fortran unformatted)

matplotlibカラープロット

gnuplotは止めました。
Pythonをメインで使ってるのにmatplotlibを使わないのが
そもそも不自然だったんですけどね。


仕事で3次元のデータ(x, y, zの組)をプロットする機会が多いので、
得たポイントをまとめておきます。

環境はAnacondaです。
外部にネットワークが接続してない環境なので、一発でインストールできるのは助かります。
DOSLINUX両方で使ってますが、今のところ大きな差異は感じません。

自分に必要なことしか調べてないので
網羅的な内容にはなりませんのであしからず。

matplotlibのカラープロット

matplotlibで3次元のデータをカラープロット(コンター図?)にする方法は
おそらく2つあります。

plt.pcolor

※2017.6.18注
plt.pcolormeshまたはpcolorfastまたはplt.imshowでも同様のプロットが可能です。
それぞれ返すオブジェクトが異なるようですが、出来上がるイメージはすべて同じだと思います。
pcolorfastが最も描画速度が速いようです。
pylab_examples example code: pcolor_demo.py — Matplotlib 2.0.2 documentation
f:id:ikarino99:20160706201755p:plain

plt.contour(+plt.contourf)

下の例にもありますが、plt.contourfが塗りつぶし、plt.contourが等高線になります。
pylab_examples example code: contour_demo.py — Matplotlib 2.0.2 documentation
f:id:ikarino99:20160706201801p:plain

#!/usr/bin/env python3
import matplotlib.pyplot as plt
import numpy as np

xs = np.arange(-5, 5, 0.1)
z = np.array([x**2 + y**2 for x in xs for y in xs]).reshape((len(xs), len(xs)))
plt.contourf(xs, xs, z)
# plt.pcolor(xs, xs, z)
plt.colorbar()
plt.show()
# plt.savefig("contouf.png")

plt.pcolorは実直にz軸データを色に変換してプロットする方法。
plt.contour(f)はz軸の値の範囲毎に色を割り当ててプロットする方法。

3次元プロットを利用する場面の多くは
視覚的なイメージを相手に植え付けることが目的で、
具体的な値を示す場面で使うことは無いと思います。

そのため、私は細かい値を気にしないplt.contour(f)をよく使います。
データ数が多いとplt.pcolorはコストがかかることも理由の一つです。


それでは以下でポイントをまとめていきます。

x軸とy軸のスケールを一致させる

横縦軸共に長さのことが多いです。
軸の単位が縦横で違っても、アスペクト比で印象が変わってきますよね。

plt.axes().set_aspect('equal')

アスペクト比を変えるとsavefigのときに白いとこが増えちゃいます。
その解決策

plt.savefig("contouf.png", bbox_inches='tight')

表示するz値の目盛り値を変える

plt.contourfの場合かなり重要。
どこを境目にするかで、印象がぜんぜん違う。
(x, y, )zの次の引数です。

levels = [0, 2, 3, 10, 56]
plt.contourf(xs, xs, z, levels)

f:id:ikarino99:20160706203551p:plain
さっきと同じデータなのに、どうしても中心部分だけに目が行きますよね。
簡単に印象操作できちゃう。これがあるからカラープロットは信頼出来ない。

表示するx,y値の目盛り値を変える(表示の角度を変える)

x軸の目盛りが多すぎて表示できなかったので、90度に変更しました。

z軸の目盛り値をログスケールにする

from matplotlib.color import LogNorm
z = z + 1
plt.contourf(xs, xs, z, norm=LogNorm())

f:id:ikarino99:20160708021927p:plain

番外編:numpy2次元配列(行列)のあれこれ

カラー表示するZ軸の値はnumpy.ndarrayの2次元配列とすると思います。
私がよく使う関数のメモ。

import numpy as np
# 回転系
z = z.T # 転置したい場合
z = np.rot90(z) # 行列を90度回転したい場合
z = np.flipud(z) # 上下逆さま
z = np.fliplr(z) # 左右逆さま
# 数値計算系
z = np.log(z) # ログスケールしたい場合
z = z * 100 # 定数倍したい場合
z = M.dot(z) # 行列Mとの積を計算したい場合