from mp_api.client import MPRester
import pandas as pd
defquery_materials_project(formula=None, elements=None,
band_gap_range=None,
e_above_hull_max=0.025):
"""
Materials Project API による材料データベース照会。
検索条件:
- 化学式 (formula) — exact or reduced
- 構成元素 (elements) — 含む/排除
- バンドギャップ範囲 (band_gap_range) — eV
- 凸包上エネルギー (e_above_hull) — 安定性指標
"""with MPRester() as mpr:
criteria = {}
if formula:
criteria["formula"] = formula
if elements:
criteria["elements"] = elements
docs = mpr.materials.summary.search(
**criteria,
energy_above_hull=(0, e_above_hull_max) if e_above_hull_max elseNone,
band_gap=band_gap_range,
fields=[
"material_id", "formula_pretty", "volume",
"density", "band_gap", "energy_above_hull",
"formation_energy_per_atom", "is_stable",
"symmetry", "nsites",
],
)
results = []
for doc in docs:
results.append({
"mp_id": doc.material_id,
"formula": doc.formula_pretty,
"space_group": doc.symmetry.symbol if doc.symmetry elseNone,
"band_gap_eV": doc.band_gap,
"e_above_hull_eV": doc.energy_above_hull,
"formation_energy_eV": doc.formation_energy_per_atom,
"density_g_cm3": doc.density,
"nsites": doc.nsites,
"is_stable": doc.is_stable,
})
df = pd.DataFrame(results)
print(f" Materials Project query:")
print(f" Found: {len(df)} materials")
iflen(df) > 0:
print(f" Stable: {df['is_stable'].sum()}")
print(f" Band gap range: {df['band_gap_eV'].min():.2f}–{df['band_gap_eV'].max():.2f} eV")
return df
3. 相図・凸包解析
import numpy as np
import pandas as pd
defcompute_phase_diagram(system_elements, output_file="figures/phase_diagram.png"):
"""
相図 (凸包) 計算。
凸包 (Convex Hull):
- 安定相: 凸包上の点 (e_above_hull = 0)
- 準安定相: 凸包上方の点 (e_above_hull > 0)
- 分解反応: 凸包上の隣接安定相への分解
"""from mp_api.client import MPRester
from pymatgen.analysis.phase_diagram import PhaseDiagram, PDPlotter
with MPRester() as mpr:
entries = mpr.get_entries_in_chemsys(system_elements)
pd_obj = PhaseDiagram(entries)
print(f" Phase diagram: {'-'.join(system_elements)}")
print(f" Total entries: {len(entries)}")
print(f" Stable phases: {len(pd_obj.stable_entries)}")
for entry in pd_obj.stable_entries:
formula = entry.composition.reduced_formula
e_form = pd_obj.get_form_energy_per_atom(entry)
print(f" {formula}: ΔHf = {e_form:.4f} eV/atom")
# 可視化
plotter = PDPlotter(pd_obj)
plotter.get_plot().savefig(output_file, dpi=300, bbox_inches="tight")
return pd_obj
4. 電子バンド構造・DOS
import numpy as np
defplot_band_structure(material_id, output_file="figures/band_structure.png"):
"""
電子バンド構造の取得と可視化。
- 高対称 k-path (Setyawan-Curtarolo 規約)
- バンドギャップ判定 (直接/間接)
- フェルミレベル基準
"""from mp_api.client import MPRester
from pymatgen.electronic_structure.plotter import BSPlotter
with MPRester() as mpr:
bs = mpr.get_bandstructure_by_material_id(material_id)
if bs isNone:
print(f" No band structure available for {material_id}")
returnNone
gap = bs.get_band_gap()
print(f" Band structure: {material_id}")
print(f" Band gap: {gap['energy']:.3f} eV")
print(f" Direct: {gap['direct']}")
print(f" Transition: {gap['transition']}")
plotter = BSPlotter(bs)
plotter.get_plot().savefig(output_file, dpi=300, bbox_inches="tight")
return bs
defplot_density_of_states(material_id, output_file="figures/dos.png"):
"""
電子状態密度 (DOS) の取得と可視化。
- Total DOS + projected DOS (元素分解)
- スピン偏極 (該当時)
"""from mp_api.client import MPRester
from pymatgen.electronic_structure.plotter import DosPlotter
with MPRester() as mpr:
dos = mpr.get_dos_by_material_id(material_id)
if dos isNone:
print(f" No DOS available for {material_id}")
returnNoneprint(f" DOS: {material_id}")
print(f" Efermi: {dos.efermi:.3f} eV")
plotter = DosPlotter()
plotter.add_dos("Total", dos)
plotter.get_plot().savefig(output_file, dpi=300, bbox_inches="tight")
return dos