curve_fit报错RuntimeError:最优参数未找到,求拟合与绘图解决方案
Birch-Murnaghan EOS拟合报错解决及数据处理方案
报错原因分析
RuntimeError: Optimal parameters not found: The maximum number of function evaluations is exceeded 本质是初始参数猜测不合理,或数据存在异常,导致curve_fit迭代至最大次数仍无法收敛到最优解。Birch-Murnaghan EOS是强物理约束的方程,初始参数必须贴合数据的物理意义,不能随意赋值。
1. 修正拟合逻辑与参数初始化
标准Birch-Murnaghan EOS形式
def birch_murnaghan(V, V0, B0, B0_prime, E0): eta = (V / V0) ** (1/3) return E0 + (9 * B0 * V0 / 16) * ( (eta**2 - 1)**3 * B0_prime + (eta**2 - 1)**2 * (6 - 4*eta**2) )
其中:
V0:平衡体积(能量最小值对应的体积)B0:体积模量(典型值30~200 GPa,依材料而定)B0_prime:模量导数(经验值3~5,常用4)E0:平衡能量(数据中的最小能量值)
初始参数估算规则
从原始数据中直接提取关键初始值,而非盲目赋值:
E0取数据中的最小能量V0取对应最小能量的体积B0设为同类型材料的典型值(如30 GPa)B0_prime设为4(通用经验值)
2. 完整可运行代码
import numpy as np from scipy.optimize import curve_fit import matplotlib.pyplot as plt # 定义Birch-Murnaghan EOS方程 def birch_murnaghan(V, V0, B0, B0_prime, E0): eta = (V / V0) ** (1/3) return E0 + (9 * B0 * V0 / 16) * ( (eta**2 - 1)**3 * B0_prime + (eta**2 - 1)**2 * (6 - 4*eta**2) ) # 加载数据(替换为你的数据加载方式,如np.loadtxt/pd.read_csv) # 假设数据格式为:第一列体积V,第二列能量E DataHT = np.loadtxt('DataHT.txt') V_ht, E_ht = DataHT[:, 0], DataHT[:, 1] DataLT = np.loadtxt('DataLT.txt') V_lt, E_lt = DataLT[:, 0], DataLT[:, 1] # 估算高温数据初始参数 E0_ht_init = np.min(E_ht) V0_ht_init = V_ht[np.argmin(E_ht)] p0_ht = [V0_ht_init, 30, 4, E0_ht_init] # 估算低温数据初始参数 E0_lt_init = np.min(E_lt) V0_lt_init = V_lt[np.argmin(E_lt)] p0_lt = [V0_lt_init, 30, 4, E0_lt_init] # 执行拟合,增大迭代次数兜底 try: popt_ht, pcov_ht = curve_fit(birch_murnaghan, V_ht, E_ht, p0=p0_ht, maxfev=10000) popt_lt, pcov_lt = curve_fit(birch_murnaghan, V_lt, E_lt, p0=p0_lt, maxfev=10000) except RuntimeError as e: print(f"拟合失败: {e}") exit() # 输出拟合参数 print("=== 高温样本拟合参数 ===") print(f"平衡体积V0: {popt_ht[0]:.4f}") print(f"体积模量B0: {popt_ht[1]:.4f} GPa") print(f"模量导数B0': {popt_ht[2]:.4f}") print(f"平衡能量E0: {popt_ht[3]:.4f}") print("\n=== 低温样本拟合参数 ===") print(f"平衡体积V0: {popt_lt[0]:.4f}") print(f"体积模量B0: {popt_lt[1]:.4f} GPa") print(f"模量导数B0': {popt_lt[2]:.4f}") print(f"平衡能量E0: {popt_lt[3]:.4f}") # 绘制拟合曲线 plt.figure(figsize=(10,6)) # 高温数据与拟合曲线 V_fit_ht = np.linspace(np.min(V_ht), np.max(V_ht), 100) E_fit_ht = birch_murnaghan(V_fit_ht, *popt_ht) plt.scatter(V_ht, E_ht, label='高温样本数据', color='crimson', s=25) plt.plot(V_fit_ht, E_fit_ht, label='高温拟合曲线', color='darkred', linewidth=2) # 低温数据与拟合曲线 V_fit_lt = np.linspace(np.min(V_lt), np.max(V_lt), 100) E_fit_lt = birch_murnaghan(V_fit_lt, *popt_lt) plt.scatter(V_lt, E_lt, label='低温样本数据', color='steelblue', s=25) plt.plot(V_fit_lt, E_fit_lt, label='低温拟合曲线', color='darkblue', linewidth=2) plt.xlabel('体积 V') plt.ylabel('能量 E') plt.title('Birch-Murnaghan EOS拟合结果') plt.legend() plt.grid(alpha=0.3) plt.show()
3. 额外排查建议
- 如果仍报错,先绘制原始数据散点图,检查是否存在异常值(如能量随体积变化无明显极小值),或数据范围过窄/过宽
- 若材料已知,可调整
B0的初始值至该材料的典型模量范围,进一步提高收敛概率 maxfev仅作为兜底参数,优先保证初始参数的合理性,否则迭代次数再多也无法收敛
内容的提问来源于stack exchange,提问作者Erwann
相关产品推荐
相关产品推荐

