ASE全局优化实操:Basin hopping
同一个Cu13小团簇,用普通FIRE和六次basin扰动对照,说明完整建模、温度单位、局部淬火与最低能提取。
阅读本篇目录
普通结构优化通常沿着当前位置附近的势能面下降,可能停在某个局部极小。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/;再次操作请用新解压目录。

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的一般优化与计算器入口见官方文档。