首页/文章/ 详情

直观感受动力学数值解法的误差

15分钟前浏览16

▲图1

图1所示的模型,弹簧刚度为    ,忽略其他因素,把小车从平衡位置往右移动    ,小车由初始位移开始自由振动,它经过平衡位置后,弹簧开始压缩,直到质量块达到    ,之后小车又开始往右运动。在该系统振动过程中没有摩擦力,也没有外力作用于小车。理论上,小车的位移区间是    

下面来看看数值解:

import numpy as np
import matplotlib.pyplot as plt

def main(steps, dt):
    k = 3    # 弹簧刚度
    x = 0.5   # 初始位移
    m = 1     #质量
    v1 = 0   # 初始速度
    x1 = x

    xxx = np.zeros(steps)

    for i in range(steps):
        a  = -k *x1 /m   # 加速度
        v2 = v1 + a* dt   # 下一时刻的速度
        x2 = x1 + v1*dt + 0.5 * a * dt **2# 下一时刻的位移
        # 上述三个公式是中学物理的公式
        v1 = v2
        x1 = x2
        xxx[i] = x2

    fig, ax = plt.subplots(11, figsize=(10,6) )
    ax.plot(range(steps), xxx, 'r-')
    ax.set_xlabel('$t/s$',fontsize = 14)
    ax.set_ylabel('$x2/m$',fontsize = 14)

    fig.savefig('f46.png', dpi = 400
    plt.show()       



if __name__ == "__main__":
    main(2000.1)

▲图2

由图2可知,小车的振幅在不断增加,已经超过了理论上的    这个范围了。

▲图3

考虑图3所示的一个时间步长    。存在两个时间点    和    。粗线表示弹簧的内力。在此期间,小车正在移动,弹簧内力也随之变化。加速度与力直接相关,因此随着力的变化,加速度也会变化。然而,在同一时间段内,Python脚本使用的是    时刻的弹簧内力计算了加速度的值,并在整个时间步长内使用该值。在代码中,加速度和力在整个时间步长内保持不变。因此,数值模拟中的力不是图3所示的曲线,而是一条直线(如虚线所示)。

▲图4

实际上,物理方程描述的是一个在时间上连续的系统,而Python脚本描述的是一个具有离散时间步长的系统,图4展示了实际力(曲线)和用于数值计算的力(阶梯线)。在    附近,由于曲线趋于将阶梯线一分为二,因此数值模拟产生的误差不大。误差是两条曲线之间的面积,且曲线上下两侧的面积大致相等。在顶部和底部峰值处,计算力并不能模拟实际的力。因此,精度损失会逐渐累积。

▲图5

来看另一个例子。如图5所示的单自由度体系,简谐荷载    作用在质点上,    

根据图5b的弯矩图可求得柔度系数

 

自振频率为

 

动力系数

 

则质点的动位移表达式

 

令    ,用Newmark方法求解,并和解析解对比。

import numpy as np
import matplotlib.pyplot as plt

# Newmark方法

def newmark1(steps, dt):

    M = 1
    K = 3
    F = 1

    U_0 = 0   #初始位移
    V_0 = 0   #初始速度
    A_0 = 0   #初始加速度

    # 参数
    alpha = 0.5; beta = 0.25
    c0 = 1/(beta * dt**2)
    c1 = alpha /(beta * dt)
    c2 = 1/(beta * dt)
    c3 = 1/(2*beta) - 1
    c4 = alpha /beta - 1
    c5 = dt * (alpha /(2*beta ) - 1)
    c6 = dt * (1- alpha )
    c7 = alpha * dt


    # 有效刚度矩阵
    KK = K + c0 * M 
    invKK = 1/KK


    data = np.zeros( steps ) # 存储各时间步长下的位移

    for i in range(steps):
        H = c0 * U_0 + c2 * V_0 + c3 * A_0
        F_1 = np.sin(0.5 * dt*i) * F + M * H   #简谐荷载
        U_1 = invKK * F_1
        data[i ] = U_1

        ## t+dt时刻的速度和加速度
        A_1 = c0 *(U_1 - U_0) - c2*V_0 -c3*A_0
        V_1 = V_0 + c6* A_0 + c7* A_1

        A_0 = A_1
        U_0 = U_1
        V_0 = V_1


    time = np.zeros(steps)
    data1 = np.zeros(steps)
    for i in range(steps):
        t = dt * i
        time[i] = t
        data1[i] = np.sin(0.5 * dt*i) * 1.2 * 0.4


    plt.rcParams['font.sans-serif'] = ['Noto Sans SC']    # 这个字体能够支持中英文字符
    plt.rcParams['axes.unicode_minus'] = False      # 正常显示负号

    fig, ax = plt.subplots(11, figsize=(8,4) )
    ax.plot(time, data, 'r-', label='数值方法')
    ax.plot(time, data1, color='k', linestyle='--', label='解析法')
    ax.legend(frameon=True,         # 启用边框
        framealpha=0.8,             # 设置透明度
        fancybox=False,             # 边框圆角与否
        shadow=True,                # 是否启用阴影
        facecolor='lightgrey',      # 背景颜色
        edgecolor='dimgrey',       # 边框颜色
        loc= 'upper right'
    
    ax.set_xlabel('$t/s$',fontsize = 14)
    ax.set_ylabel('$y/m$',fontsize = 14)

    fig.savefig('f99.png', dpi = 300
    plt.show()



if __name__ == "__main__":
    newmark1(2000.2)


▲图6

由图6可知,数值解和解析解在平衡位置相对误差不大,而在峰值位置相对误差较大。

来源:数值分析与有限元编程
STEPS振动pythonUM理论
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2025-11-23
最近编辑:15分钟前
太白金星
本科 慢慢来
获赞 12粉丝 28文章 367课程 0
点赞
收藏
作者推荐

力学概念 | 共振现象

▲图1作用在结构上的非对称竖向荷载,使结构产生水平位移。即由竖向荷载引发的框架结构水平运动,如图1所示。具体分析见力学概念|竖向荷载引起的结构水平位移如果作用在结构上的是动荷载,且频率接近结构的某阶水平振型频率,结构会在竖向激励作用下发生沿水平方向的共振。框架杆件有分布质量,只考虑3个动力自由度,如图2所示。▲图2设振型矩阵为其中为一阶振型。现用振型分解法求水平动位移将统一用表示,3个动力自由度的无阻尼强迫振动方程为写成矩阵形式其中结构的任意位移都是三个振型的线性组合。其中是广义坐标。写成矩阵形式其中(4)代入(2)得(5)左乘由振型向量的正交性质为广义质量。同理为广义刚度。所以,广义坐标下的运动方程为其中的一个方程为(8)即为体系按第振型的振动分量用广义坐标表达的运动方程,共计有3个方程。这3个方程之间是相互独立、无耦合关系的,每一个方程均可按单自由度体系的运动方程求解。求得后,再通过(4),得到结构的位移。(8)两边同时除以得简谐荷载作用下,(9)的特解为其中,代入(10)得若一阶频率无限接近动荷载的频率,即,那么由(4)可得图1的框架,其一阶振型不是对称的,而是"一边倒"的。这说明了一个重要的现象:如果作用在结构上的竖向动荷载频率接近结构的一阶水平振型频率,结构会在竖向激励作用下发生沿水平方向的共振。来源:数值分析与有限元编程

未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈