You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在scipy.integrate.solve_ivp中传入矩阵求解多自由度振动方程?

多自由度弹簧-质量-阻尼系统通用求解方案(基于scipy.solve_ivp)

scipy.integrate.solve_ivp本身没有内置直接传入质量、刚度、阻尼矩阵的参数,但你可以通过编写通用的一阶方程右函数实现和Matlab ode45相同的效果,无需逐行编写每个一阶方程,适配任意自由度的系统,具体实现逻辑如下:

核心原理

n自由度弹簧-质量-阻尼系统的控制方程为通用形式:
$$ M \ddot{x} + C \dot{x} + K x = F(t) $$
其中:

  • $M$ 为n×n质量矩阵
  • $C$ 为n×n阻尼矩阵
  • $K$ 为n×n刚度矩阵
  • $x$ 为n×1位移向量,$\dot{x}$ 为速度向量,$\ddot{x}$ 为加速度向量
  • $F(t)$ 为n×1时变外力向量

转换为一阶状态方程时,定义2n维状态向量 $y = \begin{bmatrix} x \ \dot{x} \end{bmatrix}$,则一阶导数可统一写为:
$$ \dot{y} = \begin{bmatrix} \dot{x} \ \ddot{x} \end{bmatrix} = \begin{bmatrix} y[n:] \ M^{-1} \cdot (F(t) - C \cdot y[n:] - K \cdot y[:n]) \end{bmatrix} $$
该公式对任意n值均成立,不需要针对不同自由度修改逻辑。

通用代码实现

你只需要提前定义好对应维度的M、C、K矩阵和外力函数F(t),不需要逐行编写每个一阶方程,以下是适配你2DOF示例的通用版本代码,直接替换M/C/K和F(t)的定义即可适配30自由度甚至更高维度的系统:

from scipy.integrate import solve_ivp
import numpy as np
import matplotlib.pyplot as plt

# -------------------------- 仅需修改以下参数即可适配不同自由度系统 --------------------------
# 系统参数(以2DOF为例,30自由度则对应生成30×30的M/C/K矩阵即可)
n = 2  # 自由度数量
M = np.diag([3, 5])  # 质量矩阵
C = np.array([
    [1+2, -2],
    [-2, 2]
])  # 阻尼矩阵
K = np.array([
    [7+9, -9],
    [-9, 9]
])  # 刚度矩阵

# 时变外力函数,输入t返回n维外力向量
def external_force(t):
    f1 = 40 * np.cos(3*t)
    f2 = 4 * np.sin(t**2)
    return np.array([f1, f2])

# 求解配置
start_time = 0
end_time = 60
delta_t = 0.1
# 初始条件:前n个为各质量初始位移,后n个为各质量初始速度
initial_conditions = np.array([6, 9, 0, 4])
# ----------------------------------------------------------------------------------------

# 通用右函数,任意n自由度均不需要修改
def F(t, y):
    dy_dt = np.zeros(2*n)
    # 前n维为位移的导数(即速度)
    dy_dt[:n] = y[n:]
    # 后n维为速度的导数(即加速度),用solve替代inv计算更稳定
    dy_dt[n:] = np.linalg.solve(M, external_force(t) - C @ y[n:] - K @ y[:n])
    return dy_dt

# 求解
time_interval = [start_time, end_time]
sol = solve_ivp(F, time_interval, initial_conditions, max_step=delta_t)

T = sol.t
Y = sol.y

注意事项

  • 30自由度对应的状态向量仅60维,属于极小规模的ODE问题,numpy的矩阵运算效率远高于手动逐行写方程,无需担心性能问题
  • 针对更大规模的系统,如果M为稀疏矩阵,可以替换np.linalg.solve为scipy.sparse.linalg.spsolve进一步提升计算效率
  • 该写法和Matlab中传入矩阵给ode45的逻辑完全一致,仅需要提前组装好对应维度的矩阵即可

内容的提问来源于stack exchange,提问作者user15014634

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 01:48:03