mcpField
P
pymatgen

pymatgen

github.com/jaechang-hitsデータ・データベース38471 回インストール1 週間前に更新
リポジトリ

pymatgen について

pymatgenは、結晶構造や材料データを扱う研究者向けの材料科学計算用Pythonライブラリです。多様な形式の構造データを統一的に扱い、解析やMaterials Projectの検索、計算入力の生成を行えます。

主な機能

  1. 01結晶と分子の統一データモデル
  2. 02多様な構造ファイル形式の読み書き
  3. 03Materials Projectの物性検索
  4. 04対称性と状態図の解析
  5. 05XRD回折パターンのシミュレーション
  6. 06DFT入力ファイルの生成

活用シーン

  1. 01CIF、POSCAR、XYZファイルの変換
  2. 02計算済み材料物性の取得
  3. 03熱力学的な相安定性の評価
  4. 04VASP計算入力の準備

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill pymatgen

インストール後、Claude Code で/pymatgenを入力して読み込まれたか確認します。

詳細

pymatgen

概要

pymatgen は、材料科学の計算における標準的な Python ライブラリです。中核となるデータモデルである Structure(周期結晶材料)と Molecule(非周期系)は、30 種類以上のファイル形式(CIF、POSCAR/CONTCAR、XYZ、PDB、Gaussian、VASP)にわたる入出力を統一的に表現できます。このライブラリは Materials Project REST API(mp_api)と連携し、バンドギャップ、生成エネルギー、弾性定数を含む、DFT で計算された 150,000 件以上の構造を取得できます。pymatgen は、ハイスループット DFT 用の atomate2 および Custodian ワークフローフレームワークの基盤です。

使用する場面

  • CIF、POSCAR、XYZ などの形式間で結晶構造ファイルを解析、変換する
  • Materials Project API に問い合わせて、計算済みのバンドギャップ、生成エネルギー、安定性データを取得する
  • 熱力学的安定性を調べるため、相図と Pourbaix 図を作成、解析する
  • 構造オブジェクトから VASP、Quantum ESPRESSO、CP2K の入力ファイルを生成する
  • 実験結果と比較するため、X 線回折(XRD)および中性子回折パターンを計算する
  • 結晶構造の対称性、空間群、Wyckoff 位置を解析する
  • 分子動力学を実行する場合や、統一されたランナーを介して複数の MD/DFT コードと連携する場合は、ASE を使用する

前提条件

  • Python パッケージ:pymatgen、mp-api(Materials Project クライアント)
  • データ要件:構造ファイル(CIF、POSCAR)または Materials Project API キー
  • API キー:materialsproject.org で無料取得できます — PMG_MAPI_KEY 環境変数を設定します
pip install pymatgen mp-api
# Set API key
export PMG_MAPI_KEY="your_api_key_here"
# Or via pymatgen config
python -c "from pymatgen.core import SETTINGS; SETTINGS['PMG_MAPI_KEY'] = 'your_key'"

クイックスタート

from pymatgen.core import Structure, Lattice, Species

# Build silicon diamond cubic structure from scratch
a = 5.431  # Angstroms
lattice = Lattice.cubic(a)
silicon = Structure(
    lattice=lattice,
    species=["Si", "Si"],
    coords=[[0, 0, 0], [0.25, 0.25, 0.25]],
)
print(f"Silicon: {silicon.formula}, {silicon.volume:.2f} ų")
print(f"Space group: {silicon.get_space_group_info()}")
# Silicon: Si2, 40.89 ų
# Space group: ('Fd-3m', 227)

コア API

モジュール 1:Structure と Lattice

周期結晶の中核となるデータ構造です。

from pymatgen.core import Structure, Lattice, Element, Species
import numpy as np

# From lattice parameters
lattice = Lattice.from_parameters(a=4.05, b=4.05, c=4.05,
                                   alpha=90, beta=90, gamma=90)

# Build FCC aluminum
al_fcc = Structure(lattice, ["Al", "Al", "Al", "Al"],
                   [[0, 0, 0], [0.5, 0.5, 0], [0.5, 0, 0.5], [0, 0.5, 0.5]])

print(f"Formula: {al_fcc.formula}")
print(f"Sites: {len(al_fcc)}")
print(f"Volume: {al_fcc.volume:.3f} ų")
print(f"Density: {al_fcc.density:.3f} g/cm³")

# Access sites
for site in al_fcc:
    print(f"  {site.species_string} at {site.frac_coords}")
# Load from file
from pymatgen.core import Structure

# From CIF (most common exchange format)
struct = Structure.from_file("material.cif")

# From POSCAR (VASP format)
struct_vasp = Structure.from_file("POSCAR")

# Get neighbors within cutoff
site = struct[0]
neighbors = struct.get_neighbors(site, r=3.0)
print(f"Neighbors within 3 Å: {len(neighbors)}")
for nn in neighbors[:3]:
    print(f"  {nn.species_string}: {nn.nn_distance:.3f} Å")
モジュール 2:Materials Project API クエリ

DFT で計算された 150,000 件以上の材料の特性を取得します。

from mp_api.client import MPRester
import os

api_key = os.environ.get("PMG_MAPI_KEY", "your_key")

with MPRester(api_key) as mpr:
    # Search by chemical system
    docs = mpr.materials.summary.search(
        chemsys=["Li-Fe-O"],
        fields=["material_id", "formula_pretty", "energy_above_hull",
                "band_gap", "is_stable"]
    )
    print(f"Li-Fe-O materials: {len(docs)}")
    for d in docs[:5]:
        print(f"  {d.material_id}: {d.formula_pretty}, "
              f"Eg={d.band_gap:.2f} eV, above_hull={d.energy_above_hull:.3f} eV/atom")
# Get specific material by MP ID
with MPRester(api_key) as mpr:
    doc = mpr.materials.summary.get_data_by_id(
        "mp-149",  # Silicon
        fields=["structure", "band_gap", "formation_energy_per_atom",
                "density", "is_stable", "symmetry"]
    )
    struct = doc.structure
    print(f"Si mp-149: band_gap={doc.band_gap:.3f} eV, "
          f"density={doc.density:.3f} g/cm³")
    print(f"Space group: {doc.symmetry.symbol}")
モジュール 3:対称性解析
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer
from pymatgen.core import Structure

struct = Structure.from_file("material.cif")

# Symmetry analysis
sga = SpacegroupAnalyzer(struct, symprec=0.1)

print(f"Space group: {sga.get_space_group_symbol()} ({sga.get_space_group_number()})")
print(f"Crystal system: {sga.get_crystal_system()}")
print(f"Point group: {sga.get_point_group_symbol()}")

# Get conventional / primitive cell
primitive = sga.get_primitive_standard_structure()
conventional = sga.get_conventional_standard_structure()
print(f"Primitive: {len(primitive)} sites | Conventional: {len(conventional)} sites")

# Wyckoff positions
sym_dataset = sga.get_symmetry_dataset()
print(f"Wyckoff letters: {set(sym_dataset['wyckoffs'])}")
モジュール 4:相図

熱力学的安定性と相境界を解析します。

from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter
from mp_api.client import MPRester
import os

api_key = os.environ.get("PMG_MAPI_KEY", "your_key")

with MPRester(api_key) as mpr:
    # Get all entries in the Li-Fe-P-O chemical system
    entries = mpr.get_pourbaix_entries(["Li", "Fe"])

# For phase diagram, use computed entries
with MPRester(api_key) as mpr:
    entries = mpr.get_entries_in_chemsys(["Li", "Fe", "O"])

pd = PhaseDiagram(entries)
print(f"Stable phases: {len(pd.stable_entries)}")

# Check stability of a specific composition
from pymatgen.core import Composition
comp = Composition("LiFeO2")
e_hull = pd.get_e_above_hull(pd.qhull_entries[0])
print(f"E above hull: {e_hull:.3f} eV/atom")

# Plot (requires matplotlib)
plotter = PDPlotter(pd, backend="matplotlib")
plotter.show()
モジュール 5:XRD パターンシミュレーション
from pymatgen.analysis.diffraction.xrd import XRDCalculator
from pymatgen.core import Structure
import matplotlib.pyplot as plt

struct = Structure.from_file("material.cif")  # or build programmatically

# Calculate XRD pattern (Cu Kα radiation, λ = 1.5406 Å)
calculator = XRDCalculator(wavelength="CuKa")
pattern = calculator.get_pattern(struct, two_theta_range=(10, 80))

print(f"Diffraction peaks: {len(pattern.x)}")
for two_theta, intensity, hkl in zip(pattern.x[:5], pattern.y[:5], pattern.hkls[:5]):
    print(f"  2θ={two_theta:.2f}°, I={intensity:.1f}, hkl={hkl}")

# Plot
fig, ax = plt.subplots(figsize=(10, 4))
ax.bar(pattern.x, pattern.y, width=0.3, color="black")
ax.set_xlabel("2θ (degrees)")
ax.set_ylabel("Intensity (arb. units)")
ax.set_title(f"XRD Pattern — {struct.formula}")
plt.tight_layout()
plt.savefig("xrd_pattern.pdf", bbox_inches="tight")
モジュール 6:DFT 入力ファイルの生成

DFT 計算用の VASP 入力セットを生成します。

from pymatgen.io.vasp.sets import MPRelaxSet, MPStaticSet
from pymatgen.core import Structure

struct = Structure.from_file("material.cif")

# Generate VASP relaxation input set (Materials Project standard)
relax_set = MPRelaxSet(struct)

# Write to directory
import os
os.makedirs("vasp_relax", exist_ok=True)
relax_set.write_input("vasp_relax")
print("Generated: POSCAR, INCAR, KPOINTS, POTCAR (requires VASP pseudopotentials)")

# Inspect key INCAR settings
incar = relax_set.incar
print(f"ENCUT: {incar.get('ENCUT')} eV")
print(f"KPOINTS: {relax_set.kpoints}")

# For static calculation after relaxation
static_set = MPStaticSet.from_prev_calc(prev_calc_dir="vasp_relax")
static_set.write_input("vasp_static")

重要な概念

分率座標と直交座標

pymatgen の Structure は、原子位置を分率座標(格子ベクトルに対する相対座標、範囲は 0~1)で保持します。struct.lattice.get_cartesian_coords(frac) または struct.lattice.get_fractional_coords(cart) を使って、直交座標(オングストローム)との変換ができます。ほとんどのファイル形式では直交座標が使われますが、pymatgen は読み込み時と書き込み時に自動で変換します。

組成と酸化状態

Composition("LiFePO4") は化学式を解析します。Structure.add_oxidation_state_by_guess() は結合原子価を用いて、Pourbaix 図や一部の物性計算に必要な形式電荷(+Li、-O など)を割り当てます。

一般的なワークフロー

ワークフロー 1:ハイスループット安定性スクリーニング
from mp_api.client import MPRester
from pymatgen.analysis.phase_diagram import PhaseDiagram
import pandas as pd, os

api_key = os.environ.get("PMG_MAPI_KEY", "your_key")

# Screen lithium-transition-metal oxides for stability
systems = [f"Li-{m}-O" for m in ["Mn", "Co", "Ni", "Fe", "V"]]
results = []

with MPRester(api_key) as mpr:
    for system in systems:
        docs = mpr.materials.summary.search(
            chemsys=[system],
            fields=["material_id", "formula_pretty", "energy_above_hull",
                    "band_gap", "is_stable", "formation_energy_per_atom"]
        )
        for d in docs:
            results.append({
                "system": system,
                "mpid": d.material_id,
                "formula": d.formula_pretty,
                "e_above_hull": d.energy_above_hull,
                "band_gap": d.band_gap,
                "stable": d.is_stable,
            })

df = pd.DataFrame(results)
stable = df[df["stable"] == True].sort_values("band_gap")
print(f"Stable phases: {len(stable)}/{len(df)}")
print(stable[["formula", "system", "band_gap", "e_above_hull"]].head(10))
stable.to_csv("stability_screen.csv", index=False)
ワークフロー 2:構造の操作とエクスポート
from pymatgen.core import Structure
from pymatgen.transformations.standard_transformations import (
    SupercellTransformation, SubstitutionTransformation
)

# Load and analyze structure
struct = Structure.from_file("material.cif")
print(f"Original: {struct.formula}, {len(struct)} sites")

# Create 2×2×2 supercell
sc_matrix = [[2, 0, 0], [0, 2, 0], [0, 0, 2]]
supercell = SupercellTransformation(sc_matrix).apply_transformation(struct)
print(f"Supercell: {len(supercell)} sites")

# Substitute element (e.g., 10% Fe doping on Mn sites)
sub = SubstitutionTransformation({"Mn": {"Mn": 0.9, "Fe": 0.1}})
doped = sub.apply_transformation(struct)
print(f"Doped composition: {doped.composition.reduced_formula}")

# Export in multiple formats
struct.to(filename="output.cif")            # CIF
struct.to(filename="POSCAR")               # VASP POSCAR
struct.to(filename="output.xyz")           # XYZ
print("Exported CIF, POSCAR, XYZ")

主なパラメーター

パラメーターモジュール/関数デフォルト範囲/オプション効果
symprecSpacegroupAnalyzer0.010.01–0.5 Å対称性検出の許容誤差。大きいほど許容範囲が広くなります
wavelengthXRDCalculator"CuKa""CuKa"、"MoKa"、浮動小数点数(Å)回折シミュレーションで使用する X 線の波長
two_theta_rangeXRDCalculator.get_pattern(0, 90)度数のタプルXRD パターンの角度範囲
ENCUTMPRelaxSet INCAR520 eV300–800 eVVASP の平面波エネルギーカットオフ
chemsysMPRester.search—["Li-Fe-O"]Materials Project クエリの化学系フィルター
fieldsMPRester.searchすべて文字列のリストAPI 転送量を減らすため、返されるフィールドを制限します
rStructure.get_neighbors—1–8 Å近傍検索のカットオフ半径

よく使うレシピ

レシピ:CIF を一括で POSCAR に変換
from pymatgen.core import Structure
from pathlib import Path

cif_dir = Path("cif_files")
poscar_dir = Path("poscar_files")
poscar_dir.mkdir(exist_ok=True)

for cif_path in cif_dir.glob("*.cif"):
    try:
        struct = Structure.from_file(str(cif_path))
        out_path = poscar_dir / f"{cif_path.stem}_POSCAR"
        struct.to(filename=str(out_path))
        print(f"Converted: {cif_path.name} → {out_path.name}")
    except Exception as e:
        print(f"FAILED {cif_path.name}: {e}")
レシピ:材料のリストからバンドギャップを取得
from mp_api.client import MPRester
import pandas as pd, os

mp_ids = ["mp-149", "mp-2815", "mp-1265"]  # Si, GaAs, TiO2

api_key = os.environ.get("PMG_MAPI_KEY", "your_key")
with MPRester(api_key) as mpr:
    docs = mpr.materials.summary.get_data_by_ids(
        mp_ids, fields=["material_id", "formula_pretty", "band_gap", "is_gap_direct"]
    )

df = pd.DataFrame([{
    "mpid": d.material_id,
    "formula": d.formula_pretty,
    "band_gap_eV": d.band_gap,
    "direct_gap": d.is_gap_direct,
} for d in docs])
print(df.to_string(index=False))

トラブルシューティング

問題原因解決策
APIError: Invalid API keyPMG_MAPI_KEY が設定されていないか、期限切れです環境変数を設定します:export PMG_MAPI_KEY="your_key"。materialsproject.org でキーを再生成します
SpacegroupAnalyzer が誤った空間群を返す原子位置にわずかな乱れがあるか、symprec が厳しすぎますsymprec を 0.01 から 0.1 に増やします。まず get_refined_structure() を使用します
CIF の Structure.from_file が失敗するDisorder、部分占有、または標準外の CIF ですCifParser(file).get_structures(primitive=False) を使用します。occupancy_tolerance=2.0 を設定します
MPRester がハングするかタイムアウトする数千件の結果を返す大規模なクエリですfields=["material_id", "formula_pretty"] を追加してペイロードを減らします。chunk_size を使用します
VASP 入力セットで POTCAR が見つからないVASP 擬ポテンシャルライブラリが設定されていませんpmg config --add PMG_VASP_PSP_DIR /path/to/potpaw を実行します
大きなスーパーセルでメモリエラーが発生するスーパーセルに数千個の原子が含まれていますスーパーセルのサイズを小さくします。Structure.get_sorted_structure() を使用してから、段階的に書き込みます
XRDCalculator のピークがゼロになる構造にサイトが 1 つしかないか、すべて同じ元素種です複数サイトの構造を使用します。print(struct) で構造が正しく読み込まれていることを確認します

関連スキル

  • pymoo — pymatgen の記述子を使用した、材料特性スクリーニングのための多目的最適化
  • autodock-vina-docking — 分子ドッキング向けの、pymatgen に類似した構造準備ワークフロー
  • zarr-python — MD 軌跡や特性データベースの大規模配列を効率的に保存

参考資料

コメント