如何使用scipy.optimize.curve_fit成功完成Morse势能的数据拟合
拟合失败原因
- 势能函数定义缺失偏移项:当前使用的Morse势能默认平衡位置
r=r0处势能为0,但你的能量数据整体偏移到了-1428左右的区间,没有偏移项的情况下,拟合算法只能通过将D设为负值来匹配负的能量结果,自然不符合物理意义。你之前拟合简谐势能失败也是同样的原因。 - 初始参数设置不合理:给定的D初始值0.005远小于实际阱深(你的数据阱深约为0.17),alpha初始值10也远高于常规双原子分子的alpha取值范围(通常1~3 Å⁻¹),算法很容易收敛到错误的局部最优解甚至发散。
修正方案
1. 调整Morse势能函数定义
增加阱底能量偏移项E0,匹配能量数据的整体偏移:
import numpy as np def morsePotential(r, D, alpha, r0, E0): return D * (1 - np.exp(-alpha * (r - r0)))**2 + E0
2. 设置合理初始参数
直接从原始数据估算初始值,大幅降低算法收敛难度:
- D(阱深):能量最大值 - 能量最小值 ≈ (-1428.04) - (-1428.21) ≈ 0.17
- r0(平衡键长):能量最低点对应的距离,你的数据中为1.02
- alpha:初始值取2,属于双原子分子的合理取值范围
- E0(阱底能量):能量最小值 ≈ -1428.21
3. 增加参数物理约束
给curve_fit增加参数边界,避免输出不符合物理意义的参数:
from scipy.optimize import curve_fit distances = np.array([0.7, 0.78, 0.86, 0.94, 1.02, 1.1, 1.18, 1.26]) energies = np.array([-1428.03995379, -1428.13375727, -1428.18294153, -1428.20472839, -1428.20977469, -1428.2047732, -1428.19393863, -1428.17996123]) # 初始参数顺序:D, alpha, r0, E0 p0 = [0.17, 2, 1.02, -1428.21] # 参数边界:D>0, alpha>0, r0在0.9~1.1之间,E0在-1428.3~-1428.1之间 bounds = ([0, 0, 0.9, -1428.3], [1, 10, 1.1, -1428.1]) param, cv = curve_fit(morsePotential, distances, energies, p0=p0, bounds=bounds) D, alpha, r0, E0 = param
4. 可选优化
如果仍出现拟合不稳定的情况,可以先将能量数据减去最小值做归一化,拟合完成后再还原到原始能量区间,进一步降低数值计算误差。
内容的提问来源于stack exchange,提问作者poisonDartFrog
相关产品推荐
相关产品推荐

