Files
solidstate-tools/dpgen/transport.py
koko bd4bd3a645 LiYCl
朱一舟
2025-10-16 16:49:33 +08:00

76 lines
3.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from typing import List, Dict, Tuple
def add_li_y_antisite_average(
x: float,
# Y 位点:[(label, wyckoff, (fx,fy,fz), occ, multiplicity)]
y_sites: List[Tuple[str, str, Tuple[float, float, float], float, int]] = None,
# Li 位点:[(label, wyckoff, (fx,fy,fz), occ, multiplicity)]
li_sites: List[Tuple[str, str, Tuple[float, float, float], float, int]] = None,
# 可选:各位点的 B 因子(字典),不需要可留空
b_iso: Dict[str, float] = None,
# 保留小数位
ndigits: int = 4
) -> str:
"""
把结构改写成含 x (相对于 Y 总数) 的 Li/Y 反位缺陷的“平均占据”CIF 块。
返回字符串,可直接粘贴到 CIF 的 atom_site loop 中。
"""
# 默认使用表 S9P-3̅m1的坐标与占据multiplicity 依据该空间群
if y_sites is None:
y_sites = [
("Y1", "1a", (0.0000, 0.0000, 0.0000), 1.0000, 1),
("Y2", "2d", (0.3333, 0.6666, 0.4880), 0.8269, 2),
("Y3", "2d", (0.3333, 0.6666,-0.0650), 0.1730, 2),
]
if li_sites is None:
li_sites = [
("Li1", "6g", (0.3397, 0.3397, 0.0000), 1.0000, 6),
("Li2", "6h", (0.3397, 0.3397, 0.5000), 0.5000, 6),
]
if b_iso is None:
# 可按需要改
b_iso = {"Y": 1.10, "Li": 5.00, "Cl": 1.99}
# 1) 总 Y 与总 Li每原胞的“原子数贡献”
y_total = sum(m * occ for _,_,_,occ,m in y_sites) # 期望为 3
li_total = sum(m * occ for _,_,_,occ,m in li_sites) # 期望为 9
# 2) 需要交换的“Y 数量”(相对于每原胞)
y_exchanged = x * y_total # 例如 x=0.0556 → ~0.1668 个 Y/原胞
# 3) 折算到 Li 子格的分配比例(保证电中性和计量)
li_fraction = y_exchanged / li_total # 每个 Li 位点应引入的 Y 的比例
# 4) 生成 CIF loop 文本(同一坐标写两行,分别为主元素与反位元素)
lines = []
header = [
"loop_",
" _atom_site_label",
" _atom_site_type_symbol",
" _atom_site_fract_x",
" _atom_site_fract_y",
" _atom_site_fract_z",
" _atom_site_occupancy",
" _atom_site_B_iso_or_equiv",
]
lines.extend(header)
# 4a) 处理 Y 位点Y → (1-x)*occLi_on_Y → x*occ
for label, wyck, (fx,fy,fz), occ, mult in y_sites:
y_main_occ = round(occ * (1.0 - x), ndigits)
li_on_y_occ = round(occ * x, ndigits)
lines.append(f" {label}_main Y {fx:.4f} {fy:.4f} {fz:.4f} {y_main_occ:.{ndigits}f} {b_iso.get('Y',1.0)}")
lines.append(f" Li_on_{label} Li {fx:.4f} {fy:.4f} {fz:.4f} {li_on_y_occ:.{ndigits}f} {b_iso.get('Li',5.0)}")
# 4b) 处理 Li 位点Li → (1-li_fraction)*occY_on_Li → li_fraction*occ
for label, wyck, (fx,fy,fz), occ, mult in li_sites:
li_main_occ = round(occ * (1.0 - li_fraction), ndigits)
y_on_li_occ = round(occ * li_fraction, ndigits)
lines.append(f" {label}_main Li {fx:.4f} {fy:.4f} {fz:.4f} {li_main_occ:.{ndigits}f} {b_iso.get('Li',5.0)}")
lines.append(f" Y_on_{label} Y {fx:.4f} {fy:.4f} {fz:.4f} {y_on_li_occ:.{ndigits}f} {b_iso.get('Y',1.0)}")
return "\n".join(lines)
# === 示例 ===
# x=0.0556(与论文使用的 5.56% 一致,定义为相对于 Y 总数的比例):
print(add_li_y_antisite_average(0.0556))