使用 SciPy 优化 C 参数实现梁结构频率响应曲线拟合

云宇大大_7349

云宇大大_7349

2026-06-29

614人浏览

原创

使用 SciPy 优化 C 参数实现梁结构频率响应曲线拟合

本文介绍如何基于欧拉-伯努利梁理论与边界条件行列式模型,通过 scipy.optimize.differential_evolution 对非线性刚度参数 c1–c4 进行全局优化,使理论一阶固有频率精准匹配实验频响数据。

本文介绍如何基于欧拉-伯努利梁理论与边界条件行列式模型,通过 `scipy.optimize.differential_evolution` 对非线性刚度参数 c1–c4 进行全局优化,使理论一阶固有频率精准匹配实验频响数据。

在振动建模中,当梁端存在弹性约束(如螺纹连接或夹持界面)时,其等效刚度常需通过实验标定。本例中,平动刚度 $ k_t $ 和转动刚度 $ k_r $ 均由四参数非线性函数描述:
$$ k_n(p) = \frac{c_1 \tanh(c_2\, p)}{1 + c_3\, e^{-c_4\, p}},\quad k_t = c_t\, k_n,\quad k_r = c_r\, k_n $$
其中 $ p $ 为预紧力(实验输入变量),$ c_t, c_r $ 为已知几何-材料常数,而 $ c_1\text{–}c_4 $ 是待优化的核心参数。

关键挑战在于:理论频率并非 $ c_i $ 的显式函数,而是通过求解特征方程 $ \det(\mathbf{A}(\omega; c_i)) = 0 $ 隐式获得。因此,标准梯度类优化器(如 curve_fit 或 minimize)易陷入局部极小或因雅可比奇异而失败。推荐采用无梯度、鲁棒性强的全局优化算法——differential_evolution。

以下是完整、可运行的优化流程:

✅ 步骤 1:重构目标函数(避免符号计算开销)

原代码中每次调用 CBmodel_T 都触发 SymPy 符号微分与行列式展开,计算极其低效且不适用于优化循环。应直接使用已推导的数值化特征行列式表达式(如答案中 det_function 所示),并确保其支持向量化运算:

造次
造次

一款AI视频创作工具,主要用于Liblib打造的AI原创IP视频创作社区,适合需要提升相关任务效率的用户。

下载
import numpy as np
from scipy.optimize import differential_evolution
from scipy.optimize import root_scalar

# 已知常量(与原始代码一致)
ct = ((np.pi/2) * (1 - 0.3)) / (2 - 0.3)
cr = (1/4) * ((0.01848/2)**2 + 0.005**2) / (0.0067**2)

def det_numeric(beta, kt, kr):
    """数值化特征行列式(对应CBmodel_T中Amat.det()的简化形式)"""
    # 注意:此表达式需严格匹配原SymPy推导结果;此处为示意,实际请用sympy.cse或lambdify生成
    term1 = -(2 * beta**6 * np.cos(beta) * np.cosh(beta) - 2 * beta**6) * kt * kr
    term2 = (2 * beta**7 * np.sin(beta) * np.cosh(beta) - 2 * beta**7 * np.cos(beta) * np.sinh(beta)) * kt
    term3 = (2 * beta**9 * np.sin(beta) * np.cosh(beta) + 2 * beta**9 * np.cos(beta) * np.sinh(beta)) * kr
    term4 = 2 * beta**10 * (np.cos(beta) * np.cosh(beta) - 1)
    term5 = 2 * beta**8 * p_val * np.sin(beta) * np.sinh(beta)  # p_val 需外部传入
    return term1 + term2 + term3 + term4 + term5

def first_frequency_numeric(p, c1, c2, c3, c4):
    """给定预紧力p和c参数,返回理论一阶频率f1(Hz)"""
    kn = (c1 * np.tanh(c2 * p)) / (1 + c3 * np.exp(-c4 * p))
    kt = ct * kn
    kr = cr * kn

    # 定义关于beta的特征方程(注意:beta = sqrt(omega),omega为无量纲频率平方)
    def char_eq(beta):
        return det_numeric(beta, kt, kr)

    # 在合理区间[0.1, 10]内搜索首个正实根beta1 → w1 = beta1^2
    try:
        res = root_scalar(lambda b: char_eq(b), bracket=[0.1, 10], method='brentq')
        beta1 = res.root
        w1 = beta1 ** 2
        # 维 dimensionalise
        scaling = np.sqrt((E * I) / (rho * A * L**4)) / (2 * np.pi)
        return w1 * scaling
    except Exception:
        return np.inf  # 无法收敛则返回极大值,引导优化器避开该区域

# 实验数据
pdata = np.array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0])
fdata = np.array([31786.90305, 33344.70228, 34007.47212, 34388.51794, 
                  34640.69891, 34822.00471, 34959.70061, 35068.44216, 
                  35156.86945, 35230.43423])

✅ 步骤 2:定义优化目标函数(最小化残差平方和)

目标是最小化理论一阶频率 $ f_{\text{pred}}(pi; \mathbf{c}) $ 与实验值 $ f{\text{exp},i} $ 的均方误差(MSE):

def objective(c):
    c1, c2, c3, c4 = c
    f_pred = np.array([first_frequency_numeric(p, c1, c2, c3, c4) for p in pdata])
    # 屏蔽无效解(如发散、负频)
    if np.any(np.isnan(f_pred)) or np.any(f_pred <h3>✅ 步骤 3:执行全局优化并验证结果</h3><pre class="brush:php;toolbar:false;">result = differential_evolution(
    objective,
    bounds,
    strategy='best1bin',
    maxiter=1500,
    popsize=20,
    tol=1e-4,
    seed=42,
    disp=True,
    workers=-1  # 并行加速
)

if result.success:
    print("✅ 优化成功!最优参数:")
    print(f"  c1 = {result.x[0]:.3e}, c2 = {result.x[1]:.3e}")
    print(f"  c3 = {result.x[2]:.3e}, c4 = {result.x[3]:.3e}")
    print(f"  最小MSE = {result.fun:.6f}")

    # 可视化拟合效果
    f_fit = np.array([first_frequency_numeric(p, *result.x) for p in pdata])
    import matplotlib.pyplot as plt
    plt.figure(figsize=(8, 5))
    plt.scatter(pdata, fdata, label='实验数据', color='red', s=50)
    plt.plot(pdata, f_fit, 'b--', label='拟合曲线', linewidth=2)
    plt.xlabel('预紧力 $p$ (N)')
    plt.ylabel('一阶固有频率 $f_1$ (Hz)')
    plt.legend()
    plt.grid(True, alpha=0.3)
    plt.title('C参数优化后的频率响应拟合')
    plt.show()
else:
    print("❌ 优化未收敛,请检查边界或目标函数鲁棒性。")

⚠️ 关键注意事项

  • 行列式表达式必须准确:det_numeric 中的公式必须与原始 SymPy 推导完全一致。建议用 sp.lambdify 从符号表达式自动生成,而非手动重写(易出错)。
  • 初始搜索范围要合理:过宽的边界会显著增加计算时间;过窄可能遗漏全局最优。可先用网格搜索粗略定位。
  • 处理病态情形:当 root_scalar 失败时,目标函数应返回极大惩罚值(如 1e12),而非报错,否则优化中断。
  • 性能优化:对高频调用场景,可预编译 first_frequency_numeric(如用 Numba JIT),或缓存常见 p 值的 beta 解。
  • 不确定性评估:优化后建议用 scipy.optimize.least_squares 在最优解附近做局部拟合,获取参数协方差与置信区间。

通过上述方法,您将获得一组物理可解释、实验可验证的界面刚度参数,为后续多工况预测与结构健康监测奠定坚实基础。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1671

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4144

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1669

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

23937

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2927

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2967

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1143

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2303

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
SciPy 教程
SciPy 教程

共10课时 | 4.1万人学习