154 lines
4.1 KiB
Python
154 lines
4.1 KiB
Python
"""
|
||
pymatgen skill helpers — 建材院无机材料场景常用映射 + MPRester 封装。
|
||
|
||
LLM 通过 `from skills.pymatgen.materials import CEMENT_PHASES, mp_rester` 使用。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import os
|
||
from contextlib import contextmanager
|
||
|
||
|
||
# 中文/简写 → 化学式映射。覆盖建材院 R&D 高频物相。
|
||
# 添加新条目时:
|
||
# - key 用用户最自然的称呼(中文 / 行业简写),value 是 mp 能识别的化学式
|
||
# - 同一物相多种叫法都加 key,指向同一化学式(C3S / 硅酸三钙 / 阿利特 都是 Ca3SiO5)
|
||
CEMENT_PHASES: dict[str, str] = {
|
||
# ---- 硅酸盐水泥熟料矿物 ----
|
||
"C3S": "Ca3SiO5",
|
||
"硅酸三钙": "Ca3SiO5",
|
||
"阿利特": "Ca3SiO5",
|
||
"alite": "Ca3SiO5",
|
||
|
||
"C2S": "Ca2SiO4",
|
||
"硅酸二钙": "Ca2SiO4",
|
||
"贝利特": "Ca2SiO4",
|
||
"belite": "Ca2SiO4",
|
||
|
||
"C3A": "Ca3Al2O6",
|
||
"铝酸三钙": "Ca3Al2O6",
|
||
|
||
"C4AF": "Ca4Al2Fe2O10",
|
||
"铁铝酸四钙": "Ca4Al2Fe2O10",
|
||
"铁相": "Ca4Al2Fe2O10",
|
||
|
||
# ---- 水化产物 ----
|
||
"C-S-H": "Ca1.5SiO3.5·xH2O",
|
||
"水化硅酸钙": "Ca1.5SiO3.5·xH2O",
|
||
|
||
"CH": "Ca(OH)2",
|
||
"氢氧化钙": "Ca(OH)2",
|
||
"portlandite": "Ca(OH)2",
|
||
"钙矾石": "Ca6Al2(SO4)3(OH)12·26H2O",
|
||
"AFt": "Ca6Al2(SO4)3(OH)12·26H2O",
|
||
"ettringite": "Ca6Al2(SO4)3(OH)12·26H2O",
|
||
|
||
"AFm": "Ca4Al2(OH)12(SO4)·6H2O",
|
||
"单硫型水化硫铝酸钙": "Ca4Al2(OH)12(SO4)·6H2O",
|
||
|
||
# ---- 石膏 / 硫酸盐 ----
|
||
"石膏": "CaSO4·2H2O",
|
||
"二水石膏": "CaSO4·2H2O",
|
||
"gypsum": "CaSO4·2H2O",
|
||
"半水石膏": "CaSO4·0.5H2O",
|
||
"硬石膏": "CaSO4",
|
||
"anhydrite": "CaSO4",
|
||
|
||
# ---- 碳酸盐 / 碳化产物 ----
|
||
"方解石": "CaCO3",
|
||
"calcite": "CaCO3",
|
||
"文石": "CaCO3",
|
||
"aragonite": "CaCO3",
|
||
|
||
# ---- 陶瓷 / 耐火常见相 ----
|
||
"莫来石": "Al6Si2O13",
|
||
"mullite": "Al6Si2O13",
|
||
|
||
"堇青石": "Mg2Al4Si5O18",
|
||
"cordierite": "Mg2Al4Si5O18",
|
||
|
||
"刚玉": "Al2O3",
|
||
"α-Al2O3": "Al2O3",
|
||
"corundum": "Al2O3",
|
||
|
||
"方镁石": "MgO",
|
||
"periclase": "MgO",
|
||
|
||
"尖晶石": "MgAl2O4",
|
||
"spinel": "MgAl2O4",
|
||
|
||
"锆英石": "ZrSiO4",
|
||
"zircon": "ZrSiO4",
|
||
|
||
"石英": "SiO2",
|
||
"quartz": "SiO2",
|
||
|
||
"方石英": "SiO2",
|
||
"cristobalite": "SiO2",
|
||
|
||
"鳞石英": "SiO2",
|
||
"tridymite": "SiO2",
|
||
|
||
# ---- 玻璃常见组分晶相 ----
|
||
"钙长石": "CaAl2Si2O8",
|
||
"anorthite": "CaAl2Si2O8",
|
||
"钠长石": "NaAlSi3O8",
|
||
"albite": "NaAlSi3O8",
|
||
"硅灰石": "CaSiO3",
|
||
"wollastonite": "CaSiO3",
|
||
"透辉石": "CaMgSi2O6",
|
||
"diopside": "CaMgSi2O6",
|
||
|
||
# ---- 其他常见 ----
|
||
"白云石": "CaMg(CO3)2",
|
||
"dolomite": "CaMg(CO3)2",
|
||
"赤铁矿": "Fe2O3",
|
||
"hematite": "Fe2O3",
|
||
"磁铁矿": "Fe3O4",
|
||
"magnetite": "Fe3O4",
|
||
}
|
||
|
||
|
||
def lookup_phase(name: str) -> str:
|
||
"""中文/简写相名 → 化学式。命中返回化学式,未命中抛 KeyError(带建议)。"""
|
||
if name in CEMENT_PHASES:
|
||
return CEMENT_PHASES[name]
|
||
# 大小写不敏感再查一遍
|
||
lower = name.lower()
|
||
for k, v in CEMENT_PHASES.items():
|
||
if k.lower() == lower:
|
||
return v
|
||
raise KeyError(
|
||
f"{name!r} 不在 CEMENT_PHASES 映射表里。"
|
||
f"若是新相,直接把化学式喂给 pymatgen / Materials Project;"
|
||
f"若高频用,补到 skills/pymatgen/materials.py 的 CEMENT_PHASES。"
|
||
)
|
||
|
||
|
||
@contextmanager
|
||
def mp_rester(api_key: str | None = None):
|
||
"""
|
||
MPRester 上下文管理器封装,自动从 env(MP_API_KEY)拿 key。
|
||
|
||
用法:
|
||
with mp_rester() as mpr:
|
||
docs = mpr.materials.summary.search(formula="Ca3SiO5")
|
||
|
||
Args:
|
||
api_key: 显式传入则用,否则读 env MP_API_KEY。
|
||
|
||
Raises:
|
||
RuntimeError: env 未配置且未传入 api_key。
|
||
"""
|
||
key = api_key or os.environ.get("MP_API_KEY")
|
||
if not key:
|
||
raise RuntimeError(
|
||
"MP_API_KEY not set in env. "
|
||
"申请: https://materialsproject.org/api,然后写到项目根 .env 文件。"
|
||
)
|
||
from mp_api.client import MPRester # 局部 import,避免装包前 import skill 就崩
|
||
|
||
with MPRester(api_key=key) as mpr:
|
||
yield mpr
|