CP2Kのトラジェクトリ可視化
CP2KでMD計算する場合、出力形式としてXYZ形式を選択することが多い。しかし、このXYZ形式ではセル情報が書き込まれていない。そのため、OVITOやVMDなどで可視化する際、周期境界条件として認識してくれない。また、OVITOでは、セルの大きさが時間ごとに自動変更されてしまい、時系列全体で共通のセル情報を保持できない。困った。
CP2Kではセル情報を含んでいるPDB形式も選択できるが、OVITOではPDB形式の時系列データは認識してくれない。時系列を多数のPDB形式ファイルに分割して読み込めば、アニメーション化できるが、ファイル数が多くなるのも嫌。
Extended XYZ形式
XYZ形式の発展型としてExtended XYZ形式がある(Atomsk, Format: XYZ)。これはXYZ形式にセル、速度、その他の情報を追加した形式。OVITOも対応している。これならbashスクリプトで簡単に変換できると考えた。
書式としては以下のよう。
N
Lattice="a1 a2 a3 b1 b2 b3 c1 c2 c3" Properties=species:S:1:pos:R:3:aux1:R:1...auxM:R:1 Time= time
atom1 x y z prop1 prop2 prop3...propM
atom2 x y z prop1 prop2 prop3...propM
... ...
atomN x y z prop1 prop2 prop3...propM
Lattice
にはスーパーセルのa, b, c軸ベクトルの各成分を"
で挟んで記入する。Properties
は各原子の情報の書式を示している。各項目を:
でつないで指定する。最初に情報の種類を示すキーワード(species
は元素名、pos
は原子の位置、aux
はその他の情報の名前で、例えばselect
で選択状態、vel
で速度など)、次にデータの種類(S
はstring文字列・I
はinteger整数・R
はreal浮動小数点)、最後に列数。
単純なXYZ形式の場合は、元素名、x成分, y成分, z成分の情報しかないので、Properties=species:S:1:pos:R:3
でよい。
CP2Kが出力するXYZ形式のトラジェクトリデータは、コメント行にステップ番号、時刻、全エネルギーが記入されている。ここから時刻情報だけ抜き取って、eXYZ形式に流用する。
スーパーセルの情報は、別ファイルを作ってそこに書き込み、スクリプトで読み取ることにした。スーパーセル情報ファイルは、Atomskのオプションで使用するsupercell形式(Atomsk, Option: properties)を流用した。
supercell
H(1,1) H(1,2) H(1,3)
H(2,1) H(2,2) H(2,3)
H(3,1) H(3,2) H(3,3)
こうしておけば、Atomskでの処理も同じファイルで可能になる。
作成したシェルスクリプト
bashスクリプト作成初心者のため、こんな簡単な処理も苦労した。今の所ちゃんと動く。
#! /bin/bash
if [ $# -lt 2 ]; then
echo "引数が足りません"
echo "Usage: xyz2exyz.sh supercell file.xyz"
echo "supercell: スーパーセルの情報が書かれたインプットファイル名を入力してください"
echo "file.xyz: 変換元のxyzファイル名を入力してください"
exit 1
fi
CELL_DATA=$1
XYZ=$2
SUFFIX_IN=xyz
SUFFIX_OUT=exyz
# xyzファイル名の拡張子を除く
list=(${XYZ//./ })
PREFIX=${list[0]}
# exyzファイル名作成
OUTFILE=${PREFIX}.$SUFFIX_OUT
echo "supercell data file: ${CELL_DATA}"
echo "xyz file: ${XYZ}"
# ファイル読み込み
DATA=$(cat $CELL_DATA)
echo ${DATA}
count=0
while read line
do
if [[ ${line} = "supercell" ]]; then
FLAG=1
echo "supercell line"
continue
fi
if [[ ${FLAG} = 1 ]]; then
arr[${count}]="${line}"
((++count))
fi
done << EOF
$DATA
EOF
a=(${arr[0]})
b=(${arr[1]})
c=(${arr[2]})
lattice="${a[0]} ${a[1]} ${a[2]} ${b[0]} ${b[1]} ${b[2]} ${c[0]} ${c[1]} ${c[2]}"
property="species:S:1:pos:R:3"
state="Lattice=\"${lattice}\" Properties=${property} Time="
sed -r "s/(^ i =)(.*)(, time =)(.*)(, E =)(.*)/${state}\4/" $XYZ > ${OUTFILE}