ASE专题

ASE 周期轨迹展开与均方位移

读真实SiGe轨迹,先处理周期跨界、筛选移动原子,再计算MSD并解释时间单位。

更新于 2026-10-31约 4 分钟阅读按任务与环境选择适用配置
阅读本篇目录

本例使用集群现有 ASE 3.29.0、Python 3.11、NumPy 2.3.5 与 Matplotlib 3.11.2,处理已有真实 GPUMD/VASP 输出,不需要新提交 GPU 或 DFT 任务。下载完整结构、原始结果和可运行脚本,在新解压目录执行:

bash run.sh

analysis/ 保存 CSV、结果汇总和可继续使用的数据,figures/ 保存三张高清图。脚本只用一个 CPU 线程;重复运行请另解压一份,以免混入旧输出。

1. 确认轨迹帧间隔与原子身份#

这里沿用Si/Ge热接触的实际轨迹:1664 原子,x 开放、y/z 周期,两端固定组为 0。生产段 20 ps,每 1000 个 1 fs 步存一帧,共 20 帧;首帧在生产 1 ps,末帧在 20 ps,彼此跨度为 19 ps。

head -n 5 data/contact.xyz
head -n 5 data/contact-initial.xyz

本篇时间横轴从第一张存储帧开始计零,因此是 0–19 ps。传给 ASE 的时间步应为存储帧间隔 1000 fs,不能误用积分步长 1 fs。原子顺序必须在所有帧中一致;若轨迹重排了原子,要先按稳定的原子编号恢复对应。

2. 先逐帧展开周期坐标#

原子在周期方向从接近盒长移动到接近 0,真实位移可能很小,原始包裹坐标却会相差整盒。直接对包裹坐标平方会把边界跳跃误算成几十 Ų 的 MSD。

from ase.io import read
from ase.geometry import find_mic
frames = read('data/contact.xyz', ':')
unwrapped = [frames[0].copy()]
for old, new in zip(frames[:-1], frames[1:]):
    step, distance = find_mic(new.positions - old.positions,
                              new.cell, new.pbc)
    f = new.copy()
    f.positions = unwrapped[-1].positions + step
    unwrapped.append(f)

find_mic 只在周期方向取最小镜像,不会把开放 x 方向的真实位移卷回去。本例相邻存储帧的最大原子位移约 0.4643 Å,远小于周期方向半盒长 11 Å。

如果存帧太稀,原子已跨过半盒,单靠包裹坐标就不能唯一还原位移。应提高输出频率,或在 GPUMD 中直接请求 unwrapped_position 等原生未包裹坐标。变胞轨迹还需进一步明确去除晶胞形变的方式,不能不加区分套用这份固定晶胞脚本。

3. 切出真正需要分析的原子#

initial = read('data/contact-initial.xyz')
mobile = initial.arrays['group'] != 0
trajectory = [f[mobile] for f in unwrapped]

剩下 1408 个移动原子,固定的两端不参与移动原子 MSD。分元素统计时,本例有 768 个移动 Ge、640 个移动 Si。

当前 ASE DiffusionCoefficient 的 atom_indices 分母仍使用完整结构中各元素的原子数。因此选择子集时,采用上面这种先切片构建新轨迹的方式,再调用分析器;不要只传子集索引却默认分母也跟着改了。

4. 计算MSD并查看曲线#

包内脚本保存每种元素的 〈|r(t)-r(0)|²〉:

head analysis/contact-msd.csv
ls analysis/contact-mobile-unwrapped.traj
ls figures

如需单独调用 ASE 的分段分析:

from ase import units
from ase.md.analysis import DiffusionCoefficient
analysis = DiffusionCoefficient(trajectory, timestep=1000 * units.fs)
analysis.calculate(number_of_segments=2)
slopes, spread = analysis.get_diffusion_coefficients()

这里 20 帧分为两个 10 帧段。ASE 内部逐方向用 MSD_component/2 对时间做含截距拟合,再平均方向与分段。程序返回的斜率单位是 Ų/ASE时间;乘 units.fs 才是 Ų/fs。spread 是这些方向/分段斜率的散布,不能自动解释为充分统计的材料误差条。

同一真实轨迹包裹坐标与展开坐标的MSD差别

5. 为什么这里不报告扩散系数#

这份短轨迹是带温度梯度的固体热接触,不是平衡液体或长时间离子扩散采样。展开后的 MSD 大致在 0.02–0.03 Ų 附近波动,主要反映有限温度位移;把几段曲线强行拟合出斜率,不会自动变成材料自扩散系数。

要研究扩散,应选择合适的平衡采样,检查较长时间的线性区、多个时间起点、体系尺寸和独立采样;再考虑三维 MSD=6Dt、二维 MSD=4Dt 或各向异性分量的区别。此处重点是坐标展开、子集归一化和时间单位。

依据:ASE DiffusionCoefficient实际接口与单位。原始模型和生成命令见GPUMD热接触。

需要根据你的体系选择资源?联系讨论计算需求。实际可用软件与权限,以当前账户和运行环境为准。

查看配图

放大后可滚动查看细节,按 Esc 关闭。

100%查看原图 ↗