ASE专题

ASE全局优化实操:Basin hopping

同一个Cu13小团簇,用普通FIRE和六次basin扰动对照,说明完整建模、温度单位、局部淬火与最低能提取。

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

普通结构优化通常沿着当前位置附近的势能面下降,可能停在某个局部极小。Basin hopping反复“扰动坐标→局部优化→按能量接受或拒绝”,用来寻找其他较低的极小构型。本例在集群实际计算一个13原子Cu团簇,并和相同初态的普通FIRE优化对照。

这里使用ASE3.29.0内置EMT经验势、非周期边界,局部淬火最大原子力阈值0.02 eV/Å。它演示搜索操作,不是DFT铜团簇研究,也不以六次扰动证明全局最低能。

1. 下载后先看参考结果#

下载Cu13完整输入、431帧数值、读取器和画图包,新目录解压:

python3 -m zipfile -e ase-Cu13-global-optimization-wave308-*.zip .
cd ase-Cu13-global-optimization-wave308
bash preview.sh
bash run.sh

两条脚本只读取已有431帧完整坐标、力和能量,重新检查局部淬火并绘图,不重新进行优化或MD。新结果在results/、plots/;再次操作请用新解压目录。

同一Cu13初态与三条实际优化分支的较低能构型

2. 建立同一个13原子初态#

完整计算程序是附件calculate.py,关键建模部分为:

import numpy as np
from ase.cluster import Octahedron
from ase.calculators.emt import EMT

atoms = Octahedron('Cu', 3, cutoff=1, latticeconstant=3.6)
atoms.positions += np.random.default_rng(20261108).normal(
    0, 0.04, atoms.positions.shape
)
atoms.center(vacuum=5)
atoms.pbc = False
atoms.calc = EMT()

Octahedron这里生成13个Cu,小扰动为固定随机种子的0.04 Å标准差高斯位移。真空只是放置非周期团簇的盒子,边界仍为非周期;不要将这个盒子当成周期铜体相。

每条分支都从这同一个初态复制,并重新绑定EMT,不让前一条分支已经优化的坐标成为后一条的起点。

3. 普通FIRE先作为对照#

from ase.optimize import FIRE

local = atoms.copy()
local.calc = EMT()
opt = FIRE(local, logfile='optimizer.log', trajectory='optimization.traj')
opt.run(fmax=0.02, steps=1000)

本例初始势能为10.832494879 eV/Cu13,普通FIRE停在10.157378084 eV/Cu13,最终最大原子力约0.01775 eV/Å。势能零点由EMT定义;正值本身不能解释成这个团簇是否存在或稳定,比较这里相同模型和原子数的能量变化即可。

4. 六次Basin hopping扰动#

from ase.optimize.basin import BasinHopping
from ase.units import kB

trial = atoms.copy()
trial.calc = EMT()
np.random.seed(20261108)
search = BasinHopping(
    trial,
    temperature=600 * kB,
    optimizer=FIRE,
    fmax=0.02,
    dr=0.35,
    logfile='basin.log',
    trajectory='best.traj',
    optimizer_logfile='optimizer.log',
    local_minima_trajectory='local_minima.traj',
)
search.run(steps=6)

这里temperature单位是能量eV,600×kB约0.051704 eV,不是直接写600。它控制接受能量上升的尺度,不是这份非MD搜索的实际温度轨迹。dr=0.35是坐标扰动尺度,单位Å;过大可能把团簇打散,过小则容易反复回到同一个盆地。

构造时先进行一次初始局部优化,加上六次扰动,共保留七条局部极小记录。小于力阈值才表示该次局部淬火达到这里的停止条件,不表示所有其他构型都已搜索过。

5. 从头运行与读取自己的轨迹#

在资料包根目录:

cat run.slurm
sbatch run.slurm
squeue -u "$USER"

脚本在分配资源内依次运行三条分支。当前模板申请P100节点1张卡、1个CPU核,ASE EMT在CPU计算,本例不提供GPU加速结论。计算主要依赖ASE3.29.0及其NumPy/SciPy环境,不需要外部DFT程序或POTCAR。

native/已存在时停止,避免覆盖。自己的新计算日志和原生轨迹保存在native/,新的完整提取数组在my-native-fields/。

cat native/basin-hopping/basin.log
module load ase/3.29.0
python read_ase_frames.py native --output my-fields

6. 最后一帧不一定是已访问最低能#

from ase.io import read, write
states = read('native/basin-hopping/local_minima.traj', ':')
best = min(states, key=lambda a: a.get_potential_energy())
print(best.get_potential_energy())
write('best-Cu13.extxyz', best)

本次Basin hopping已访问最低淬火能量为9.361490541 eV/Cu13,相对普通FIRE降低约0.795888 eV。最后当前状态为9.361656932 eV/Cu13,与最低值不同;因此不要只取final.extxyz就标成整个搜索的最优结果。

另一种通过短MD逃逸的搜索及重复盆地判断,见Minima hopping实操。ASE的一般优化与计算器入口见官方文档。

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

查看配图

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

100%查看原图 ↗