OpenSees 模型收敛性问题
在使用 OpenSees 进行非线性模拟时,经常遇到模型不收敛的情况。本文提供一个程序包,来帮助 OpenSees 模型收敛。对于非线性比较强,迭代时出现振荡收敛的模型有一定的效果。这个程序包名称为 SmartAnalyze
。如果您已经了解什么是 SmartAnalyze
,可以直接到下载区下载程序包。还有很多其它小工具,可以在本站的下载部分按需要下载。
当模型不收敛时,控制台会提示
1 | WARNING: CTest*::test() - failed to converge |
一般来讲,返回错误代码 -3
时,就是在迭代的过程中模型不收敛。这时可以尝试使用本文提供的 SmartAnalyze
。
值得注意的是,如果返回错误代码 -2
,比如以下信息
1 | WARNING BandGenLinLapackSolver::solve() -factorization failed, matrix singular U(i,i) = 0, i= 2 |
则不是收敛性问题,而是模型刚度矩阵异常。这时需要检查模型的连接是否出错。可以借助本站的站内工具OpenSees Online Visualizer来查看模型的几何形状和振型信息。
SmartAnalyze
SmartAnalyze
是一段可复用的代码,用于帮助模型收敛。它支持两种分析模式,一种是时程分析,一种是静力分析。下面分别介绍使用方法。
用 SmartAnalyze 进行时程分析
用通常的方式进行建模。不需要指定 algorithm
、 test
和 analysis
。在分析部分,使用以下代码
1 | source SmartAnalyze.tcl |
即可。其中 $dt
为分析步长, npts
为分析步数量。
SmartAnalyze
会采用以下几种方式来改善模型的收敛性
- 如果
test
返回的范数不是过大,增加test
的次数,避免无效的迭代; - 如果增加
test
的次数无效,依用户指定改变algorithm
,对每个algorithm
都尝试 1 步骤中的改变test
次数; - 如果改变的
algorithm
都无效,减小时间步长,重新迭代; - 如果时间步长很小仍不收敛,用户可以选择放宽
test
的容许值; - 如果还是不收敛,返回错误信息。
旧版本中使用 algorithm Linear
使本步强制收敛的方法被弃用,因为基本得不到可用的结果。
SmartAnalyze
定义了很多初始值,用户可以直接使用这些初始值,也可以在模型中指定初始值。例如:
1 | set control(printPer) 20 ;# 每20次分析输出一次进度信息 |
控制参数的具体使用方法,请读者自行阅读代码中的 Readme 部分。
用 SmartAnalyze 进行静力分析
使用方法和动力分析类似。无须指定 algorithm
、 test
和 analysis
,也无须指定 integrator
。程序自动采用 DisplacementControl
来控制加载。
SmartAnalyze
要求输入一个 list 作为加载制度,可以自动完成这个加载制度的分析。例如
1 | source SmartAnalyze.tcl |
可以完成一段往复加载。其中, $node
是加载控制节点的编号, dof
是加载自由度, $step
是最大步长, $protocol
是加载制度。上例中定义的加载制度是对指定节点往复加载两次,每次位移幅值为1。注意程序默认它的首项为正。
同样,进行静力分析时,也可以重新定义程序的参数,和动力分析的参数相同。
4.0以上版本更新
从使用OpenSees以来,类似于SmartAnalyze的程序编写过很多种。SmartAnalyze 2.2是我首次公开发布的版本。这一版本通过递推调用来实现,存在的问题是代码复杂,可读性差。还有一个问题是当时程分析步长缩小之后,程序就不再跑在地震波的采样点上了,会对结果有细微的影响。在3.0版本之前,我也编写过一个递归调用的版本。但是它存在问题是,递归嵌套的次数过多的时候,TCL解释器会报错。
基于以上原因,我将代码重构为4以上版本。它混合了递推和递归两种实现方法。基本思路是,先把整个分析分解为确定长度的小块,在小块内部递归实现,而在小块外部则递推实现。对于动力分析,每个step长度作为一个小块。对于静力分析,每个不大于maxStep的长度作为一个小块。这样处理可以使代码更简洁,而又不会陷入递归陷阱。
另一个较大的变化是,对于control参数的输入,之前是采用TCL提供的 dict
的数据结构。这个数据结构与其它语言的dict很像,所以就使用了。但在使用过程中发现,dict不能直接用指针取值,而必须通过一个函数 dict get $var key
来实现。这就造成了代码看上去不够简洁。后来发现了TCL的 array
,它和其它语言的array不同,是可以设置键名的,直接通过 $
取值,要方便很多。所以决定在重构代码时,采用 array
完全替换 dict
。请用户在使用新版本时注意修改 control
的定义方法。
Tcl 版 SmartAnalyze 下载
SmartAnalyze
源代码目前托管在 Gitee
中,但是其代码挂件服务很不稳定,现在把代码复制一份放在本站内。其源文件可点此下载。推荐使用现在的4+版本。如果需要之前的3+版本,在这里下载。
Python 版 SmartAnalyze 下载
华南理工大学黄狄昉同学使用相同的算法将 SmartAnalyze 在 Python 版的 OpenSees 中实现。使用方法类似,其源文件可点此下载。在此对黄同学表示感谢!
源代码
以下源代码都托管在 Github 中,仓库地址为 https://github.com/Hanlin-Dong/SmartAnalyze ,欢迎 Pull Request。需要阅读源代码请到仓库中寻找,本页不再加载源代码。