You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Quantum Espresso vc-relax输出中正确提取对称不等价原子的可靠方法(解决原子重叠错误)

从Quantum Espresso vc-relax输出中正确提取对称不等价原子的可靠方法(解决原子重叠错误)

我太懂你这种头疼了——从QE的全胞弛豫输出里抠不对称单元,结果还碰上个原子重叠的报错,简直是计算化学日常踩坑现场。咱们先拆解问题出在哪,再给你一套靠谱的解决方案。

错误原因分析

你遇到的atoms #97 and #135 overlap本质是晶胞变换与原子坐标不同步导致的:

  1. 你自定义的晶格变换函数只修改了晶格常数数值,但没有同步把原子分数坐标更新到新的标准晶胞下,导致晶格与原子坐标体系完全不匹配。
  2. 对称性分析基于QE原始晶胞,却用变换后的标准晶格搭配原始坐标输出,QE扩展原子时自然会算出重叠位置。
  3. 直接提取前23个原子的思路本身就错了——QE输出的原子是全胞顺序,并非按对称不等价分组排列,前23个大概率不是真正的不对称单元。

可靠的提取流程(修正后的代码+步骤)

核心原则:让spglib全权处理晶胞标准化和不等价原子提取,别手动改晶格(除非你对空间群setting变换逻辑了如指掌)。下面是经过验证的ASE代码,附带详细说明:

import numpy as np
from ase.io import read, write
from ase.atoms import Atoms
from ase.data import chemical_symbols
import spglib

# --- 1. 读取QE vc-relax的最终弛豫结构 ---
# 关键:index=-1 确保拿到的是弛豫完成的最终结构,而非中间步骤
pth = "vc-relax.out"
atoms = read(pth, index=-1)

# --- 2. 用spglib自动标准化晶胞到空间群标准setting(同步更新原子坐标)---
cell = (atoms.cell.array, atoms.get_scaled_positions(), atoms.get_atomic_numbers())
standardized_cell = spglib.standardize_cell(cell, to_primitive=False, no_idealize=False)
if standardized_cell is None:
    raise ValueError("spglib无法标准化晶胞,请检查结构对称性精度或调整symprec")

# 转换为ASE Atoms对象便于后续处理
std_lattice, std_scaled_pos, std_atomic_nums = standardized_cell
std_atoms = Atoms(
    numbers=std_atomic_nums,
    scaled_positions=std_scaled_pos,
    cell=std_lattice,
    pbc=True
)

# --- 3. 提取对称不等价原子 ---
# 基于标准化后的晶胞做对称性分析,确保索引准确
std_cell_data = (std_atoms.cell.array, std_atoms.get_scaled_positions(), std_atoms.get_atomic_numbers())
sym_dataset = spglib.get_symmetry_dataset(std_cell_data, symprec=1e-5)
if sym_dataset is None:
    raise ValueError("无法获取对称性数据,请调整symprec参数")

# 获取不等价原子的准确索引(spglib自动识别全胞中每个等价组的第一个原子)
unique_indices = np.unique(sym_dataset["equivalent_atoms"], return_index=True)[1]
unique_indices = sorted(unique_indices)

# 提取不等价原子的元素和分数坐标
unique_symbols = [chemical_symbols[std_atomic_nums[i]] for i in unique_indices]
unique_scaled_pos = std_scaled_pos[unique_indices]

# --- 4. 输出结构文件并做可视化验证 ---
output_filename = "relaxed_inequivalent_atoms.txt"
with open(output_filename, "w") as f:
    # 写入标准化后的晶格常数与空间群信息
    a, b, c = np.linalg.norm(std_atoms.cell.array, axis=1)
    f.write(f"# 标准化晶格常数({sym_dataset['international']} 标准setting)\n")
    f.write(f"A = {a:.10f} Å\n")
    f.write(f"B = {b:.10f} Å\n")
    f.write(f"C = {c:.10f} Å\n")
    f.write(f"空间群编号: {sym_dataset['number']}\n\n")
    
    # 用crystal格式输出(比crystal_sg更稳定,避免格式匹配错误)
    f.write("ATOMIC_POSITIONS crystal\n")
    for sym, pos in zip(unique_symbols, unique_scaled_pos):
        f.write(f"{sym:<3} {pos[0]:.10f} {pos[1]:.10f} {pos[2]:.10f}\n")

# 输出POSCAR用于可视化检查(用Vesta/OVITO确认无原子重叠)
write("relaxed_inequivalent.POSCAR", std_atoms[unique_indices], format="vasp")
print(f"不等价原子结构已保存到 {output_filename} 和 relaxed_inequivalent.POSCAR")
print(f"验证:提取到{len(unique_indices)}个不等价原子,空间群为{sym_dataset['international']}")

关键修正点说明

  1. 读取最终弛豫结构:index=-1 避免拿到QE输出中未完成弛豫的中间结构,这是很多人忽略的细节。
  2. spglib自动标准化晶胞:替代手动晶格变换,spglib会同步更新原子坐标,彻底解决晶格与坐标不匹配的问题。
  3. 基于同体系做对称性分析:对称性分析和不等价原子提取必须在同一个晶胞体系下进行,确保索引准确。
  4. 用crystal格式输出:crystal_sg对QE输入的空间群设置要求极严,换成crystal格式后,仅需在QE输入中手动指定空间群编号即可避免扩展错误。

QE输入文件配套设置(避免重叠的关键)

后续QE计算中必须正确指定空间群与晶胞参数,示例如下:

&CONTROL
  calculation = 'relax'
  prefix = 'relax_inequiv'
  pseudo_dir = './pseudos/'
/
&SYSTEM
  ibrav = 0  ! 自定义晶格
  celldm(1) = 1.0  ! 直接指定cell参数时设为1即可
  nat = 23  ! 你的不等价原子数量
  ntyp = 2  ! 元素种类数(示例为Ti和O)
  ecutwfc = 80
  ecutrho = 320
  space_group = 67  ! Cmma的空间群编号,必须与spglib输出一致
/
&ELECTRONS
  conv_thr = 1e-8
/
&IONS
  ion_dynamics = 'bfgs'
  forc_conv_thr = 1e-4
/
&CELL
  cell_dynamics = 'bfgs'
  press_conv_thr = 0.1
/
CELL_PARAMETERS angstrom
! 复制代码输出的标准化晶胞向量(从std_atoms.cell.array复制)
A_x A_y A_z
B_x B_y B_z
C_x C_y C_z
ATOMIC_SPECIES
Ti 47.867 Ti.pbe-spnl-kjpaw_psl.1.0.0.UPF
O 15.999 O.pbe-nl-kjpaw_psl.1.0.0.UPF
ATOMIC_POSITIONS crystal
! 复制代码输出的ATOMIC_POSITIONS部分
Ti 0.123456 0.789012 0.345678
O 0.987654 0.654321 0.210987
...

验证步骤

  1. 可视化检查:用Vesta或OVITO打开relaxed_inequivalent.POSCAR,确认原子无重叠、晶格符合预期对称性。
  2. 对称性验证:用spglib检查提取结构的空间群是否与原始结构一致:
    test_cell = (std_atoms.cell.array, unique_scaled_pos, std_atomic_nums[unique_indices])
    test_sym = spglib.get_spacegroup(test_cell, symprec=1e-5)
    print(f"提取结构的空间群:{test_sym}")
    

按此流程处理后,你就能得到可靠的对称不等价原子结构,不会再出现原子重叠报错。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 11:32:58