materialsproject.orgで開発された材料科学計算支援のPythonスクリプト. これだけ大規模なパッケージを構築できるというのはすごい,先導したリーダーと有志学生やポスドクの能力とやる気がすばらしいのだろう. しかも無料で公開しているというのも素晴らしい.

  • pymatgenサイト
  • pymatgenのバージョンは3.1.0 であったり,5.0であったり.
  • 以下はMac OS X 10.10 Yosemiteであったり,10.12 Sierraであったりでの情報.

Install

$ pip install pymatgen

でいける. pipを用いると,pymatgenが依存している他のモジュールも同時にインストールしてくれるので楽ちん. pipがインストールされていない場合はインストールした方が良い.(pythonを使う上で便利.)


CIF to POSCAR 変換

>>> from pymatgen.io.cif import CifParser
>>> parser = CifParser("test.cif")
>>> structure = parser.get_structures()[0]
>>> structure.to(filename="POSCAR")

もしくは,pmgコマンドを用いて

$ pmg structure -c -f test.cif POSCAR

のように,サブコマンドとしてstructureを指定し,そのオプションに-cconvertを指定し,-fオプションにファイル名を二つ記載することで(今の場合,CIFからPOSCARへ)変換する.


POSCAR to CIF 変換

>>> from pymatgen.io.vasp import Poscar
>>> poscar = Poscar.from_file("POSCAR")
>>> structure = poscar.structure
>>> structure.to(filename="test.cif")

Structureオブジェクト

基本はStructureオブジェクトで,pymatgen.core.structure内で定義されている.

様々な方法でStructureオブジェクトを作成できる.

  • CIFファイルやPOSCARファイルから読み込み
  • vasprun.xmlから読み込み
  • materialsproject.orgから取得
  • 地道に作る

いくつかの変数を持っている:

  • density
  • distance_matrix
  • frac_coords
  • lattice
  • reciprocal_lattice
  • sites
  • volume
  • ntypesp
  • num_sites

これらの変数は,

structure.frac_coords

のようにして呼び出すことができる.

print文で出力させると,以下のようになる.

>>> from pymatgen.io.vasp import Poscar
>>> poscar = Poscar.from_file("POSCAR")
>>> structure = poscar.structure
>>> print structure
Full Formula (Si8)
Reduced Formula: Si
abc   :   5.472000   5.472000   5.472000
angles:  90.000000  90.000000  90.000000
Sites (8)
0 Si     0.000000     0.000000     0.000000
1 Si     0.500000     0.500000     0.000000
2 Si     0.000000     0.500000     0.500000
3 Si     0.500000     0.000000     0.500000
4 Si     0.250000     0.250000     0.250000
5 Si     0.750000     0.750000     0.250000
6 Si     0.750000     0.250000     0.750000
7 Si     0.250000     0.750000     0.750000

DOSデータ取得

from pymatgen.io.vasp.vasp_output import Vasprun
from pymatgen.electronic_structure.core import Spin
 
vasprun= Vasprun("./vasprun.xml")
spd_dos= vasprun.complete_dos.get_spd_dos()
pdos= spd_dos['P'].densities[Spin.up]
sdos= spd_dos['S'].densities[Spin.up]
tdos= vasprun.complete_dos.densities[Spin.up]
energies= vasprun.tdos.energies
efermi= vasprun.efermi
 
f=open('out.dos','w')
for i in range(len(energies)):
    f.write(' {0:12.7f} {1:12.7f} {2:12.7f} {3:12.7f}\n'.format(energies[i]-efermi,tdos[i],sdos[i],pdos[i]))
f.close()

上記のようにvasprun.xmlからDOSデータを取得することができる. vasprun.xmlには多くの結果が格納されているため,上記でいうvasprunオブジェクトから様々な情報を取り出すことができる.

例えば,

N_dos= vasprun.complete_dos.get_element_spd_dos('N')

などとすると,N原子へのprojected-DOSを取り出すことができる.


Ab-initio MDのデータ取得

DOSと同様,vasprun.xmlに格納されているデータを取得する.

各ionic stepにおけるデータが出力されていないと意味がないので,VASP計算の際に,INCARにおいてNWRITE = 1を設定しておくべきだろう.

from pymatgen.io.vasp.vasp_output import Vasprun

vasprun= Vasprun("./vasprun.xml")
print vasprun.ionic_steps[0]

このionic_steps配列には,各ionic stepの情報が格納されている.


materialsproject.orgからのデータ取得

API Keyの設定

materialsproject.orgからデータを取ってくるには,そこに登録されていなければならない. 登録されていれば,API Keyの取得が可能で,そのKeyを用いてpymatgenで接続することでデータ取得が可能. materialsproject.org/dashboardで「Generate API Key」というボタンを押せばKeyが生成されるので,それをコピーする.

データ取得例:SiO2

API Keyの部分はUSER_API_KEYとしてある.

import os
from pymatgen import MPRester
api_key= "USER_API_KEY"
with MPRester(api_key) as m:
    data= m.get_data("Si1O2")

このようにMPResterというクラスを用いてデータ取得できる.

組成の指定の仕方として,Si-Oのように組成比を特に指定しない書き方や. Si-O-*のようにワイルドカードとしてどんな元素も取るというように指定することもできる.

受け取ったファイルをすべてCIF形式で保存したい場合,以下のようにする.

for d in data:
    fname = d['material_id']+'.cif'
    with open(fname,'w') as f:
        f.write(d['cif'])

POSCAR形式で保存したい場合,以下のようにする.

from pymatgen.core.structure import Structure
for d in data:
    fname = 'POSCAR_'+d['material_id']
    s = Structure.from_str(d['cif'],'cif')
    s.to(fmt='POSCAR',filename=fname)

つまり,StructureオブジェクトでCIFテキストデータを読み込み,StructureオブジェクトからPOSCAR形式で出力する.

PMG_MAPI_KEYの登録

pmg config --add PMG_MAPI_KEY <USER_API_KEY>

のように登録しておけば,生データを記入しなくてよくなるらしく,MPResterを引数なしで呼んだ場合はこれが使用されるらしい. ~/.pmgrc.yamlに保存される.

データの参照

例えば以下のようにして,データがどのようなkeyを持っているかを調べることができる.

for k,v in data[0].items():
    print k

各データのmaterial_id,空間群(space group)のsymbolnumberband_gapを表示する場合:

for i in range(len(data)):
    d= data[i]
    n= d["spacegroup"]['number']
    s= d["spacegroup"]['symbol']
    print i, d["material_id"], s, n, d["band_gap"]
0 mp-10948 Pcnb 60 5.297
1 mp-546794 I-42d 122 5.7034
2 mp-8059 P2_13 198 5.5887
3 mp-6922 P6_222 180 5.5311