pymatgen 分析模块实战:对称性、相图、能带、态密度与模型边界
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
导读
本文围绕 pymatgen 技能包中的核心分析参考文档展开,系统讲解pymatgen.analysis与pymatgen.symmetry系列 API 的正确用法:从对称性判定、结构匹配、局域配位环境,到相图、电子能带结构、态密度、衍射、表面与弹性张量分析。文中所有代码基于仓库验证的快照版本(pymatgen==2026.5.4、pymatgen-core==2026.7.16)与 skills/pymatgen 中捆绑的 CLI 脚本编写。读完本文,你将掌握如何用容差敏感性网格代替"调参凑结果",如何构建可比、可追溯的局部相图,如何正确解析 VASP 输出并区分"解析成功"与"科学结论",以及如何为每一次分析输出一份可审计的报告清单。
重要前提:本文介绍的所有分析对象——无论是对称性、配位数、带隙还是凸包——返回的只是某个特定模型与特定参数下的数值结果。一个分析对象"有返回值"并不等于建立了收敛性、不确定性、实验一致性或底层模型的适用性(见 analysis_modules.md)。
对称性分析:SpacegroupAnalyzer 与容差敏感性
对称性判定是后续许多分析(标准化、Wyckoff 位置、结构匹配)的基础。核心入口是pymatgen.symmetry.analyzer.SpacegroupAnalyzer:
from pymatgen.symmetry.analyzer import SpacegroupAnalyzer analyzer = SpacegroupAnalyzer( structure, symprec=0.01, # Å angle_tolerance=5.0, # degrees ) result = { "symbol": analyzer.get_space_group_symbol(), "number": analyzer.get_space_group_number(), "crystal_system": str(analyzer.get_crystal_system()), "point_group": analyzer.get_point_group_symbol(), "operation_count": len(analyzer.get_symmetry_operations()), } symmetrized = analyzer.get_symmetrized_structure() equivalent_indices = symmetrized.equivalent_indices wyckoff_symbols = symmetrized.wyckoff_symbolspymatgen 文档化的默认值是symprec=0.01 Å;而对于弛豫后的结构与 Materials Project 流程,更常用更宽松的0.1 Å。两组容差可能给出不同的空间群判定,因此结果会随以下因素改变:
- 坐标精度与弛豫噪声;
- 占据数 / 无序模型;
- 是否使用氧化态、自旋等位点性质;
- 原胞(primitive)还是惯用(conventional)表示;
symprec、angle_tolerance与 spglib 版本。
正确做法是:始终扫描合理的容差网格并报告完整敏感性网格,绝不为了得到想要的空间群而单方面挑选容差。
容差网格的自动化:symmetry_sensitivity_report.py
仓库在 symmetry_sensitivity_report.py 中提供了开箱即用的敏感性报告工具,其核心analyze_grid()会对symprec × angle_tolerance做笛卡尔积扫描(默认0.001,0.01,0.1Å ×1,5度),并为每个组合记录空间群符号、编号、晶系、点群、对称操作数与等价位点组数:
python skills/pymatgen/scripts/symmetry_sensitivity_report.py structure.cif \ --symprec 0.001,0.01,0.1 --angle-tolerance 1,5从源码可以看到该工具内置了严格边界:网格组合数上限 25(combinations > 25直接报错)、每种容差最多 10 个唯一值、无序结构必须显式--allow-disordered才允许分析(symmetry_sensitivity_report.py)。输出中tolerance_sensitive: True表示不同容差给出了不同空间群,此时必须连同确切的symprec与angle_tolerance一起报告,因为它不是唯一的结构不变量。测试用例可在 tests/pymatgen/test_scripts.py 中验证该脚本的依赖无关--help与合成运行行为。
标准化与原胞表示是"新表示"
get_conventional_standard_structure与get_primitive_standard_structure返回的是新的表示,而非简单变换:
conventional = analyzer.get_conventional_standard_structure( keep_site_properties=False ) primitive = analyzer.get_primitive_standard_structure( keep_site_properties=False )位点性质(site properties)可能被丢弃,也可能在无对称性感知调整的情况下被传播。务必保留父结构,并对比组成、每原子体积、磁有序与性质语义是否一致。
结构匹配:StructureMatcher 的等价语义
判断两个结构是否"等价"使用pymatgen.analysis.structure_matcher.StructureMatcher:
from pymatgen.analysis.structure_matcher import StructureMatcher matcher = StructureMatcher( ltol=0.2, stol=0.3, angle_tol=5, primitive_cell=True, scale=True, ) matches = matcher.fit(first, second)每次匹配必须记录所有容差与选项。一个"匹配"仅表示在所选算法、约化(reduction)、缩放(scaling)与物种比较器之下的等价,而不是文件身份、来源(provenance)、缺陷、磁态或实验相位的相同。
局域环境:CrystalNN 与 VoronoiNN
配位环境分析由pymatgen.analysis.local_env提供:
from pymatgen.analysis.local_env import CrystalNN, VoronoiNN crystal_nn = CrystalNN() neighbors = crystal_nn.get_nn_info(structure, 0) voronoi_nn = VoronoiNN() voronoi_neighbors = voronoi_nn.get_nn_info(structure, 0)配位数取决于方法本身、半径/氧化态信息、权重、截断、无序与几何。使用时应保留:
- 算法名称与 pymatgen 版本;
- 全部构造函数设置;
- 氧化态装饰(oxidation-state decoration);
- 位点索引/标签映射;
- 所有警告与失败记录;
- 报告的是加权配位数还是整数配位数。
同时要限制输出的位点与邻居数量;对于模型敏感的结论,用不止一种有依据的定义做交叉验证。仓库的 structure_analyzer.py 展示了带边界的 CrystalNN 实现:默认对前 100 个位点分析、每点位点最多输出 24 个邻居(--max-neighbor-sites、--max-neighbors-per-site),超出部分以neighbors_omitted计数并在 JSON 中报告coordination_is_model_dependent: True。
相图:ComputedEntry、凸包与可比性门控
一个Entry由组成(composition)与总能量(total energy)构成:
from pymatgen.analysis.phase_diagram import PhaseDiagram from pymatgen.entries.computed_entries import ComputedEntry entries = [ ComputedEntry("Li", -1.0, entry_id="local-Li"), ComputedEntry("O2", -2.0, entry_id="local-O2"), ComputedEntry("Li2O", -4.0, entry_id="local-Li2O"), ] diagram = PhaseDiagram(entries) for entry in entries: print( entry.entry_id, diagram.get_form_energy_per_atom(entry), diagram.get_e_above_hull(entry), )注意ComputedEntry.energy是所表示组成的总能量(eV),不是 eV/atom。energy_per_atom、形成能与距凸包距离(hull distance)才是归一化后的数值。
可比性门控(Comparability gate)
在构造凸包之前,必须确认所有 entry 共享兼容的:
- 泛函与修正/混合方案;
- 赝势族与价电子配置;
- 磁性、自旋与 SOC 处理;
- 参考态约定;
- 数值收敛水平;
- 温度/压力模型。
还必须包含元素端点(elemental endpoints)与所有相关竞争相——缺失相会让不稳定的 entry 看似稳定。只有当能量可比且来源(provenance)可区分时,才允许把重复组成作为多形体(polymorph)加入。diagram.stable_entries仅表示在该精确 entry 集合上的计算零温凸包上,既不等于实验稳定性,也不等于可合成性。
分解与绘图
from pymatgen.core import Composition target = Composition("Li2O", strict=True) decomposition = diagram.get_decomposition(target)对于已有 entry 使用get_e_above_hull(entry);而裸组成没有候选能量,因此它有凸包分解但没有内在的 above-hull 能量。绘图:
from pymatgen.analysis.phase_diagram import PDPlotter plotter = PDPlotter(diagram, show_unstable=0.2) plotter.write_image("phase.new.svg", image_format="svg")绘图应写入新路径、限制不稳定点数量与输出体积,并保留机器可读的 entry 表。注意绘图后端与图像导出可能引入可选依赖。
仓库中的本地相图生成器
仓库把这一套流程固化为 phase_diagram_generator.py:它完全离线,只接受严格 JSON schema 输入——顶层键必须是schema_version(严格等于"1.0")、energy_unit(严格等于"eV")、energy_basis(严格等于"total_per_entry")、provenance、entries,每个 entry 恰好包含entry_id、composition、energy_eV、provenance四个键,且energy_eV必须是有限数(phase_diagram_generator.py)。示例输入:
{ "schema_version": "1.0", "energy_unit": "eV", "energy_basis": "total_per_entry", "provenance": { "source": "reviewed local calculations", "method": "one compatible energy/correction scheme" }, "entries": [ { "entry_id": "local-Li", "composition": "Li", "energy_eV": -1.0, "provenance": {"source": "calculation manifest sha256:..."} } ] }运行与分析:
python skills/pymatgen/scripts/phase_diagram_generator.py entries.json --analyze Li2O该工具还支持--plot phase.svg --show-unstable 0.2输出 PNG/PDF/SVG 图(绘图被限制在最多四个元素,phase_diagram_generator.py),并默认在报告中显式声明三条解释边界:"hull 只对当前 entry 集合与能量模型成立""不兼容方法的能量不得混用""计算稳定性不是实验真值或合成保证"。每个 entry 的 provenance 会被作为data={"provenance": ...}保留在ComputedEntry中,从根上保证可比性门控可追溯。
化学势与 Pourbaix 分析:超越组成凸包的额外假设
ChemicalPotentialDiagram与PourbaixDiagram在组成凸包之上引入了更多假设。必须记录:参考态、开放物种、水相离子数据、浓度、pH、电化学势、温度、修正与溶剂约定。不要把固相 entry 集合直接当作有效的水相热力学模型使用——缺少必要的变换与参考态时这是错误的。
电子能带结构:Vasprun 解析与带隙的方法依赖
from pymatgen.io.vasp import Vasprun run = Vasprun( "vasprun.xml", parse_dos=False, parse_eigen=True, parse_projected_eigen=False, parse_potcar_file=False, ) bands = run.get_band_structure(line_mode=True) gap = bands.get_band_gap() vbm = bands.get_vbm() cbm = bands.get_cbm() metal = bands.is_metal()报告带隙结果时必须同时报告:
- 源计算与收敛状态;
- 结构校验和;
- 泛函、赝势、DFT+U、自旋、SOC;
- k 点网格/路径与线模式重构方式;
- Fermi 能约定及任何覆盖;
- 占据/展宽(smearing)设置;
- 直接/间接带隙判据与数值容差。
DFT 带隙是方法依赖的。Materials Project 官方资料明确说明其 PBE 带隙被系统性低估。BSPlotter可以为BandStructureSymmLine绘图,但绘图不会验证 k 路径——高对称路径取决于晶体学设置与磁性原胞假设。仓库技能在 SKILL.md 中反复强调:解析成功不等于计算收敛,parse_projected_eigen=True可能消耗极端时间与内存。
态密度:CompleteDos 与投影一致性
from pymatgen.io.vasp import Vasprun run = Vasprun( "vasprun.xml", parse_dos=True, parse_eigen=False, parse_projected_eigen=False, parse_potcar_file=False, ) dos = run.complete_dos element_dos = dos.get_element_dos() site_dos = dos.get_site_dos(run.final_structure[0]) orbital_dos = dos.get_spd_dos()检查项包括:能量网格与参考/Fermi 能级;密度单位与归一化;自旋通道与 SOC;展宽与积分方法;投影基组与完整性;DOS 位点与最终结构的一致性。在约定匹配之前,不要跨计算比较积分/投影 DOS。
VASP 解析成本:只解析所需数据
Vasprun(parse_projected_eigen=True)可能需要极端的时间与内存。当只需要本征值/能带信息时,应使用为能带解析优化的BSVasprun。大型 XML/HDF5/体数据文件需要设置文件大小、数组大小、位点/k 点/能带、内存与墙钟时间的边界。
仓库在 _common.py 中把这类边界固化为常量:默认输入上限 50 MiB、输出上限 20 MiB、位点上限 10 000,绝对上限分别为 512 MiB / 100 MiB / 100 000 位点。所有捆绑 CLI 都通过checked_input_file拒绝 URL 与符号链接、通过checked_output_file拒绝覆盖已存在文件,并用sha256_file计算来源校验和——这些就是"解析成本边界"在实现层的落地。
衍射:模拟图谱不等于物相鉴定
from pymatgen.analysis.diffraction.xrd import XRDCalculator calculator = XRDCalculator(wavelength="CuKa") pattern = calculator.get_pattern( structure, scaled=True, two_theta_range=(5, 90), ) for two_theta, intensity, hkls in zip( pattern.x, pattern.y, pattern.hkls, strict=True, ): print(two_theta, intensity, hkls)峰位/强度取决于辐射源、占据数、结构、仪器展宽、择优取向(preferred orientation)、温度/位移因子与理想粉末模型。模拟图谱本身不是物相鉴定结果。
表面、平板与 Wulff 形状
from pymatgen.core.surface import SlabGenerator generator = SlabGenerator( structure, miller_index=(1, 1, 1), min_slab_size=12.0, min_vacuum_size=15.0, center_slab=True, in_unit_planes=False, ) slabs = generator.get_slabs()记录体相父结构、Miller 指数约定、slab/真空层单位、终止面(termination)、对称化、偶极修正、面内胞、固定层与候选数上限。Slab 厚度与真空层是收敛参数,不是普适常数。
当前WulffShape接收平行的 Miller 指数与表面能序列:
from pymatgen.analysis.wulff import WulffShape wulff = WulffShape( structure.lattice, [(1, 0, 0), (1, 1, 0), (1, 1, 1)], [1.0, 1.1, 0.9], # one consistent energy unit per area )表面能必须共享组成/化学势、slab、泛函与面积约定,并显式报告其单位。
吸附、弹性与其他张量
AdsorbateSiteFinder只产生几何候选,不产生吸附能或偏好位点。必须限制生成的候选结构数量,并保留 slab 终止面、吸附物几何/电荷/自旋、覆盖度、取向与父结构映射。
pymatgen.analysis.elasticity表示应变、应力与弹性张量。使用前验证:Voigt 指标约定、应力符号、单位(报告的模量通常为 GPa)、参考系、晶体对称性、有限应变大小与拟合质量。力学稳定性判据取决于晶体类别与条件。
分析报告检查清单
无论执行哪类分析,输出报告都应包含:
- 来源校验和与解析器警告;
- 精确的包版本(分析结果随 pymatgen/spglib 版本变化);
- 单位与归一化方式;
- 全部容差与模型参数;
- 受限的输入/输出规模;
- 无序与氧化态处理方式;
- 收敛与不确定性证据;
- 方法特定注意事项;
- 不得仅凭计算输出声称实验真值。
仓库技能在 SKILL.md 中进一步要求创建项目锁定文件以保证可复现性:
uv init --python 3.11 uv add "pymatgen==2026.5.4" "pymatgen-core==2026.7.16" "mp-api==0.46.4" uv lock uv sync --frozen并将每次分析的输入、参数、版本、警告与父子校验和记录到工件清单(artifact_manifest.py),让"分析报告检查清单"真正可落地。
扩展阅读
- pymatgen 技能总览与工作流:核心对象、安全结构导入、转换、变换与 Materials Project 查询的全流程约束;
- 核心类参考:
Composition、Structure、Molecule、Lattice与不可变变体; - I/O 格式、VASP 与 Q-Chem:解析/写出是语义转换,格式间不存在无损保真;
- 变换与工作流:
TransformedStructure与组合爆炸边界; - Materials Project API:离线优先、
MP_API_KEY边界与来源/许可纪律; - 本分析模块的原参考文档:analysis_modules.md。
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考