Convergence Problems often occur when nonlinear analyses are run with OpenSees. In this article, a tcl program package is provided. This package helps OpenSees model to converge faster. This package is named
You can download this package from GitHub: SmartAnalyze
When the OpenSees model fails to converge, the console will print
WARNING: CTest*::test() - failed to converge
In general, if -3 error flag is returned, the convergence failure was encountered. In this time, users could try
SmartAnalyze is a reusable program package. It has two analysis types, transient analysis and static analysis. The usage and methodology is introduced, respectively.
Create models as usual. Do not call
test. Then replace the
analyze line with the following code
$dt is the time step for each analyzing step,
npts is the number of points.
SmartAnalyze take the following strategies to help the OpenSees model to converge.
- If the
testnorm is not too large, the number of iteration times in
testwill be increased;
- If step 1 does not work,
algorithmwill be changed according to the parameters given by users. For each
algorithm, try the strategy in step 1;
- If all the
algorithmdo not work, shorten the time step, and iterate again;
- If the time step is smaller then the tolerance, users can config to enlarge the test tolerance, and iterate from the initial time step again.
- If the model still do not converge, return an error message.
Note that trying to use
algorithm Linear to force converge in version 3.0 is deprecated, because the results are always bad.
Several initial configuration parameters are defined in
SmartAnalyze. Users can change these configurations in the model without changing the code in the package. For example,
set control(printPer) 20 ;# Print progress information every 20 steps.
The detailed usage of these control parameters are put in the code. Users are encouraged read it by themselves.
The usage is similar to transient analysis. Do not call
integrator. The program will use
DisplacementControl as the algorithm.
SmartAnalyze reads a user specified list as the loading protocol. It helps users to finish the whole protocol automatically. For example
This code will run a cyclic loading protocol. In this code,
$node is the node tag,
dof is the loading dof,
$step is the maximum time step,
$protocol is the loading protocol. Every item in the list is the target displacement of the
$node in the
Note that the first element of the protocol must be positive.
Similarly, the controlling configuration parameters can be set in the user’s model.
I have tried a lot of routines similar to SmartAnalyze since I started to use OpenSees. SmartAnalyze 2.2 is the first published code version. In this version, the routine is designed with recurrent procedures. The problem is that the code is complicated, and hard to read and maintain. Another problem is that for Transient analyses, if the step is shortened, the procedure will no longer run on the sampling points of the earthquake, which makes very small errors to the results. Before the first published version, I also tried to design the routine with recursive functions. However, a big problem is that the TCL interpreter do not support too many recursive calls. It will stop interpreting.
In the 4+ version, I refactored the routine with mixed recurrent and recursive functions. The basic idea is: First, divide the whole routine into several segments with fixed length. Then, run within the segment recursively, and run outside the segment recurrently. For Transient analyses, every
step is the length of the segment. For Static analyses, the control parameter
maxStep defines the maximum length of the segment. In this way, the recursive functions will not stack too much, and the code is more beautiful.
Another change is that for the parameters defined in
control, the data structure
dict was used. This data structure is very similar to the dicts in other languages, so I used it without hesitation. However, in practice, I found that the
control value cannot directly be got with pointer. Instead, a procedure
dict get $var key must be called, which makes the code ugly. Later, I found another data structure
array. This array is different from the array of other languages. Users can define array with keys. The value can be get directly with
$. This is much easier. Therefore, I moved to
array in new versions. Users are suggested to pay attention if they move from 3+ versions to 4+ versions.
Mr. Difang Huang from South China University of Technology has created a python file using identical algorithm. OpenSees python interpreter users can use it directly.
The tcl file and the python file can be downloaded from the same repository SmartAnalyze. Pull requests are welcome.