pymatgenでVASPの入力ファイルを作る

pymatgenを使うとVASPの入力ファイルを簡単に作ることができるが、公式ドキュメントにはまとまった記述がなかったので自分用に備忘録を残しておく。 正直、pymatgenのAPIドキュメントを読めばこの記事を読む必要はないと思う。

POTCAR

http://pymatgen.org/installation.html#potcar-setup に従ってpymatgenが読むPOTCARの配置場所を設定する。

まず、例えばVASPに付属しているPOTCARのディレクトリ(<EXTRACTED_VASP_POTCAR>)を<MY_PSP>以下にpymatgenが読み込める形式でコピーする:

pmg config -p <EXTRACTED_VASP_POTCAR> <MY_PSP>

次に<MY_PSP>をpymatgenが読めるようにする:

pmg config --add PMG_VASP_PSP_DIR <MY_PSP>

実は上のコマンドを実行することによって、ホームディレクトリ直下に以下の内容の.pmgrc.yamlを作成されている。

以上の設定でpymatgenからPOTCARを読み込めるようになる。 POTCARはpymatgen.io.vasp.inputs.Potcarで作ることができる。

POSCAR

pymatgen.core.Structureからpymatgen.io.vasp.inputs.Poscarで作ることができる。 既存のPOSCARからpymatgenのPoscarオブジェクトを作りたい場合はpymatgen.io.vasp.inputs.Poscar.from_fileを使えば良い。

一般にPOTCARにおける原子種の並びとPOSCARにおける原子種の並びは同じになっていなければならない(http://cms.mpi.univie.ac.at/wiki/index.php/POTCAR)。 そのため、pymatgen.io.vasp.inputs.Potcarに渡す原子種(symbols)とpymatgen.core.Structureの原子種(species)は同じになっていなければならない。 具体的には

potcar = pymatgen.io.vasp.inputs.Potcar(symbols)
structure = pymatgen.core.Structure(lattice, species, coords)
poscar = pymatgen.io.vasp.inputs.Poscar(structure)

みたいなときに

symbols == [a[0] for a in itertools.groupby(species)]

が成り立っていなければならない。

INCAR

INCARタグをキーとするdictからpymatgen.io.vasp.inputs.Incarで作ることができる。 既存のINCARからpymatgenのIncarオブジェクトを作りたい場合はpymatgen.io.vasp.inputs.Incar.from_fileを使えば良い。

KPOINTS

APIドキュメントを読めば分かるので省略。

VASPの公式チュートリアルfcc Si を計算する場合の例を示す。 擬ポテンシャルにはPBEを用いた。

import numpy as np

from pymatgen.core import Structure, Lattice
from pymatgen.io.vasp.inputs import Incar, Kpoints, Poscar, Potcar, VaspInput


def fccSi(a):
    cell = a * np.array([[0., 0.5, 0.5],
                         [0.5, 0., 0.5],
                         [0.5, 0.5, 0.]])
    coords = np.array([[0., 0., 0.]])

    struct = Structure(Lattice(cell), ['Si'], coords)
    return struct


def write_input(a, output_dir='.'):
    # poscar
    structure = fccSi(a)
    comment = None
    poscar = Poscar(structure, comment)

    # incar
    params = {
        'System': 'fcc Si',
        # not read WAVECAR, and start from superposition of atomic charge density
        'ISTART': 0, 'ICHARG': 2,
        'ENCUT': 240,
        'ISMEAR': 0, 'SIGMA': 0.1
    }
    incar = Incar(params)

    # kpoints
    kpoints = Kpoints(num_kpts=0, style="Monkhorst", kpts=((11, 11, 11), ),
                      kpts_shift=(0, 0, 0))

    # potcar
    potcar = Potcar(['Si'], 'PBE')

    # write input files
    vaspinput = VaspInput(incar, kpoints, poscar, potcar)
    vaspinput.write_input(output_dir)


if __name__ == '__main__':
    for a in np.linspace(3.5, 4.3, num=9):
        output_dir = "fccSi_{}".format(int(10 * a))
        write_input(a, output_dir)