CAE 分析中 隐式和显式时间积分算法的python程序实现

本文探讨了Dyna中显式与隐式时间积分方法,特别是Newmark法和中心差分法,在解决由质量、阻尼和弹簧组成的运动系统中的应用。通过分析不同算法的稳定性与精度,以及迭代求解过程,比较了隐式方法的高精度和显式方法的简单高效。
部署运行你感兴趣的模型镜像

前两天,同事研究Dyna的显/隐式时间积分的差异和基本原理。想来自己也有三、四年没做这方面的编程了,对同事问的一些问题也一时犯迷瞪,索性就又看了一遍书,网上找了些资料,写了点代码,理了理思路,以备不时之需。

0.前言

物理世界中,最常见的运动形式是由质量、阻尼和弹簧组成的运动系统,如图1所示,而且对应的运动方程如式1所示。

图1 运动系统

                                                                               M\cdot {u}''+C\cdot {u}'+K\cdot u =F                     (1)

式中,u为位移,其一阶倒和二阶倒分别为速度和加速度,而M,C,K分别为质量,阻尼和弹簧的刚度,F则为外部载荷。

该方程也可以写成式2的形式:

图2 受力分析

                                                                                 F_{i}+F_{d}+F_{k} =F_{ext}                                   (2)

其中,F_{i}为惯性力,F_{d}为阻尼力,F_{k}为弹簧力,Fext为外部力。可以知道,Fk为弹簧变形引起的力量,可以认为是系统内部力量,而F_{i}F_{d}不会引起系统自身的变形,因此可认为是外力的一部分。

由式1可知,运动系统方程是一个常微分方程(ODE),它的时间积分方法包括隐式积分和显式积分,这两种方法的差异在于,预测时间步和当前时间步的位移、速度和加速度之间的关系。如果,预测时间步(t+Δt)的某个变量需要考虑预测时间步(t+Δt)其他的变量,为隐式;相反,如果预测时间步(t+Δt)的变量与自身无关,至于上个时间步有关(t),则为显式。

1. 隐式时间积分

隐式积分方法有很多种,包括了我们常见的龙格库塔等方法。但在dyna中用的隐式方法为Newmark法,该方法通过将M和C引起的惯性力和阻尼力,引入两个参数\gamma\beta,从而将运动方程中的惯性力和阻尼力两项转换成了有效刚度和外部力两部分,从而运动方程转换成式3的形式。

                                                                     \bar{K}\cdot u =\bar{F}                                                            (3)

其中,\bar{K}\bar{F}如下。

                                                     \bar{K} = K(u) + (\frac{M}{\beta\Delta t^{2} }+\frac{C\cdot \gamma}{\beta\Delta t })                                            (4)

                    \bar{F} = F(t) +(\frac{M}{\beta\Delta t^{2} }+\frac{C\cdot \gamma}{\beta\Delta t })\cdot u + ({\frac{M}{\beta\Delta t} }+ C(\frac{\gamma}{\beta}-1)\cdot {u}' + (M\cdot ( \frac{1}{2\beta}-1) +\Delta t \cdot C(\frac{\gamma}{2\beta}-1)))\cdot {u}''(5)

式中,K为关于位移u的函数,F为关于时间t的函数。

	a1 = m/(beta*deltaT*deltaT) + gamma *c/(beta*deltaT)
	a2 = m/(beta*deltaT) + c*(gamma/beta-1)
	a3 = m*(1./(2*beta)-1) + deltaT*c*(gamma/(2*beta)-1)
	# effective stiffness & force k_*u=f_
	k_ = klin(u) + a1
	f_ = flin(t) + a1*u + a2*du + a3*ddu

通过求解式3,可以获得下一时间步的位移,并计算的到该位移乘以刚度所得弹簧变形力,以及相应的惯性力和阻尼力,并与下一时间步对比来确保力的平衡,保证每一时间步下的求解精度。而这一过程是方程求根的过程(也可以认为是寻找最优解的优化问题),因此可以采用Newton-Raphson迭代获得方程(式3)的根。当满足收敛准则(Rn<TOL) 的要求,迭代停止。迭代过程参见图3和图4。也正因为Newton-Raphson迭代过程的存在,单个时间步的计算上所开销的时间会大于中心差分法。

图3 Newton-Raphson迭代
图4 Newton-Raphson迭代(循环)

迭代算法程序如下:

#	Newton-Raphson
	while abs(Rn) > TOL: #Iteration convergence
		k_= k_ + a1
		dun = Rn/k_
		un = un + dun
		Rn = f_ - klin(un)*un- a1*un
#		print 'Tolerance:',abs(Rn/klin(un))

当计算得到收敛后的un(即下一时间步的位移),便可以预测下一时间步的速度{un}'和加速度{un}'',如下所示。 

# Next velocity and acceleration predict
	dun = gamma*(un-u)/(beta*deltaT) + du*(1-gamma/beta) + deltaT*ddu*(1-gamma/(2*beta))
	ddun = (un-u)/(beta*deltaT*deltaT) - du/(beta*deltaT) - ddu*(1./(2*beta)-1)

在获得了un{un}'{un}'',便可以作为下一时间步的初值,循环反复得到系统的瞬态响应。具体流程如下:

2. 显式时间积分——中心差分法

中心差分法与Newmark最大的差异在于: 该方法不求解\bar{K}\cdot u =\bar{F}的方程,而是求解M\cdot \ddot{u}=F{_{ext}}-F{_{int}}获得加速度值,并由前一时间步的速度,预测出下一时间步的速度,进一步得到位移值。在不考虑阻尼力的情况下,内力F_{int}来自于弹簧刚度k与位移u的乘积,而F_{ext}来自与外部力和惯性力。

                                                                             M\cdot {un}'' =F_{ext} - F_{int}

                                                                            {un}''= (F_{ext}-F_{int})/M

                                                                            {un}' = {un}' +{un}''\cdot \Delta t

                                                                             un = u +{un}'\cdot \Delta t

################Force###############
def CenterDiff(t,endtime,m,u,delta,du0):
	fext = flin(t)
	fint = klin(u)*u
	ddu = (fext - fint)/m
	du = du0 + ddu * delta
	u = u + du*delta
	t+=delta

 3.算法稳定性和精度对比

3.1 对比算例

时间积分方法的两个基本要求,一个是计算的稳定性,一个是计算的准确性。为了验证显式和隐式的稳定性和准确性,选择一个算例用于验正是很有必要的,本文算法参考的模型来自于(W. T. Thomson, Vibration Theory and Applications, 2nd Printing, Prentice-Hall, Inc., Englewood Cliffs, NJ, 1965, pp. 98-99.),ANSYS 手册中VME1。

图5 弹簧-质量系统瞬态仿真模型

3.2 稳定性

时间积分的稳定性组要体现在,计算过程会不会发散,即求解得到结果Rn无法小于收敛容差,这往往取决于不同算法的稳定性要求: 

图6 不同算法稳定性要求
import sympy as sp
import numpy as np

beta_val = 0
gamma_val = 0.5

sp.var(['dt','wc','beta','gamma'])
A = sp.Matrix([[1.,0.,-beta*dt*dt],[0.,1.,-gamma*dt],[wc*wc,0.,1.]])
B = sp.Matrix([[1.,dt,(0.5-beta)*dt*dt],[0.,1.,(1.-gamma)*dt],[0.,0.,0.]])
C = A.inv() * B

A_eigen = C.subs([(beta,beta_val),(gamma,gamma_val)])
res = A_eigen.eigenvals()
print (res)
# -dt**2*wc**2/2 - dt*wc*sqrt((dt*wc - 2)*(dt*wc + 2))/2 + 1
# -dt**2*wc**2/2 + dt*wc*sqrt((dt*wc - 2)*(dt*wc + 2))/2 + 1

#谱半径小于1 Ax=B 矩阵求解过程收敛

ct1 = abs(-dt**2*wc**2/2 - dt*wc*sp.sqrt((dt*wc - 2)*(dt*wc + 2))/2 + 1) <= 1
print (ct1.subs(dt,2./wc))
ct2 = abs(-dt**2*wc**2/2 + dt*wc*sp.sqrt((dt*wc - 2)*(dt*wc + 2))/2 + 1)<= 1
print (ct2.subs(dt,2./wc))
sp.plot_implicit(ct1)
sp.plot_implicit(ct2)

Newmark稳定性的判断,需要写出系统的传递矩阵(如图7),其特征值计算程序如下:

图7 传递矩阵
# -*- coding: utf-8 -*-
"""
Created on Tue Nov 20 12:41:40 2018

@author: yujin.wang
"""

import numpy as np
import matplotlib.pyplot as plt
import scipy as sci
import sys
gamma = 0.5
beta =0.25
k = 100.
m=1.
c=0
delta = 0.5
a = np.matrix([[1.,0.,-beta*delta*delta],[0.,1.,-gamma*delta],[k/m,0,1]])
b = np.matrix([[1.,delta,(1/2.-beta)*delta*delta],[0.,1.,(1.-gamma)*delta],[0,0,0]])
c = a.I*b
print np.linalg.eigvals(c)

#[-1.90808633e-16+0.j         -7.24137931e-01+0.68965517j     -7.24137931e-01-0.68965517j]

 选取不同\Delta T=0.5,0.05,0.005和\gamma=0.5,0.75,1.0,分析得到的结果绘制于图8,图中还包括了中心差分法的计算结果(cd)。可以看出在\Delta T=0.5时,稳定性方面只有平均加速方法没有发散,而在\gamma=0.5,0.75时,只有中心差分法发散。在\Delta T=0.5时,平均加速算法稳定,而线性加上速度则计算发散,如图9所示。

可以得到该系统的三个特征值,根据李雅普诺夫第一法,该系统有一个零特征值,两个有负实部共轭特征值,因此系统为临界稳定。 

 3.3 计算准确度

可以通过对不同参数演变过程的观察,可以判断不同积分算法的准确度。当\gamma=0.5时,Δt足够小时,中心差分法和Newmark法所得的结果基本一致,而当\gamma>0.5时,Newmark将会引入数值阻尼,从而引起本应周期振荡的过程趋近于稳态解(忽略惯性力),并且Δt过大,会增加数值阻尼的作用。

图8 不同参数下模型对比
图9 Newmark 线性加速法和平均加速法稳定性对比

4. 完整代码

代码中用到了闭包去获得线性插值函数,用到了递归实现Newmark时间积分。原程序下载

5.参考

https://wenku.baidu.com/view/7cabca2e2f3f5727a5e9856a561252d381eb2051

https://ww2.mathworks.cn/matlabcentral/answers/341514-newmark-s-method-for-nonlinear-systems?requestedDomain=zh

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

06-22
### 得物技术栈及开发者文档分析 得物作为一家专注于潮流商品的电商平台,其技术栈和开发者文档主要围绕电商平台的核心需求展开。以下是对得物技术栈及相关开发资源的详细解析: #### 1. 技术栈概述 得物的技术栈通常会涵盖前端、后端、移动应用开发以及大数据处理等多个领域。以下是可能涉及的主要技术栈[^3]: - **前端开发**: 前端技术栈可能包括现代框架如 React 或 Vue.js,用于构建高效、响应式的用户界面。此外,还会使用 Webpack 等工具进行模块化打包和优化。 - **后端开发**: 后端技术栈可能采用 Java Spring Boot 或 Node.js,以支持高并发和分布式架构。数据库方面,MySQL 和 Redis 是常见的选择,分别用于关系型数据存储和缓存管理。 - **移动应用开发**: 得物的移动应用开发可能基于原生技术(如 Swift/Kotlin)或跨平台框架(如 Flutter)。这有助于确保移动端应用的性能和用户体验一致性。 - **大数据云计算**: 在大数据处理方面,得物可能会使用 Hadoop 或 Spark 进行数据挖掘和分析。同时,依托云服务提供商(如阿里云或腾讯云),实现弹性扩展和资源优化。 #### 2. 开发者文档分析 类似于引用中提到的 Adobe 开发者文档模板[^2],得物也可能提供一套完整的开发者文档体系,以支持内部团队协作和外部开发者接入。以下是开发者文档可能包含的内容: - **API 文档**: 提供 RESTful API 或 GraphQL 的详细说明,帮助开发者快速集成得物的功能模块,例如商品搜索、订单管理等。 - **SDK 集成指南**: 针对不同平台(如 iOS、Android 或 Web)提供 SDK 下载和集成教程,简化第三方应用的开发流程。 - **技术博客**: 分享得物在技术实践中的经验成果,例如如何优化图片加载速度、提升应用性能等。 - **开源项目**: 得物可能将部分技术成果开源,供社区开发者学习和贡献。这不仅有助于提升品牌形象,还能吸引更多优秀人才加入。 #### 3. 示例代码 以下是一个简单的示例代码,展示如何通过 RESTful API 调用得物的商品搜索功能(假设接口已存在): ```python import requests def search_items(keyword, page=1): url = "https://api.dewu.com/v1/items/search" headers = { "Authorization": "Bearer YOUR_ACCESS_TOKEN", "Content-Type": "application/json" } params = { "keyword": keyword, "page": page, "size": 10 } response = requests.get(url, headers=headers, params=params) if response.status_code == 200: return response.json() else: return {"error": "Failed to fetch data"} # 调用示例 result = search_items("Air Jordan", page=1) print(result) ``` 此代码片段展示了如何通过 Python 请求得物的 API,并获取指定关键词的商品列表。 --- ###
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值