OpenSees Cloud

OpenSees AMI

Can't Truss It

Original Post - 20 Jul 2025 - Michael H. Scott

Visit Structural Analysis Is Simple on Substack.


Back when I was a new assistant professor in Eastchester, when I perused the latest issues of journals, I read an article that I couldn’t believe was published. So I wrote a discussion.

The article, “Nonlinear truss analysis by one matrix inversion”, was just what its title implied: the Modified Newton algorithm applied to the nonlinear analysis of trusses. The author claimed that any stiffness matrix could be assembled and then held constant during equilibrium iteration–a claim that is not entirely true.

The discussion pointed out the lack of novelty and made some other points about constant stiffness iteration and the conditions under which the approach would fail. Reading the article today still elevates my blood pressure. How could the author–and more importantly, the peer reviewers–have been unaware of Modified Newton or constant stiffness iteration?

I never attempted to OpenSees the author’s analyses prior to writing the discussion–the article’s words and lack of numerical details were enough to discuss.

But it’s never too late to do one’s due diligence.

The truss model from the article has five nodes and eight members and is devoid of a real unit system although the numbers look a lot like kip and feet.

Each member has unit cross-sectional area and elastic material stiffness of 3.0e6 units. The author uses a material stiffness of 4.32e6 units to assemble the stiffness matrix for constant stiffness equilibrium iteration.

In the article, the author performed two analyses of the truss. Although the stress-strain relationships for the truss members were clearly described, the global and local results were devoid of details and the figures in the article were of low quality even by 2005 standards.

I was unable replicate the results shown in the paper, so I’ll do some adjacent analyses here to demonstrate how constant stiffness iteration can fail.

The model definition is straightforward with a couple tweaks to make OpenSees assemble an incorrect stiffness matrix and then use that matrix for equilibrium iteration–an extreme version of initial stiffness iteration. First, an elastic material is wrapped with a Penalty material wrapper that has the additional stiffness required to reach E. The -noStress option is passed so that the wrapper only adds stiffness and not stress. Then, the -initial option is passed to the Newton algorithm.

For this example where an elastic material is the underlying stress-strain model, the -initial option is not necessary for the Newton algorithm. But if the underlying stress-strain model were nonlinear, the option is required in order to perform constant stiffness iteration with the initial stiffness.

import openseespy.opensees as ops

ops.wipe()
ops.model('basic','-ndm',2,'-ndf',2)

ops.node(1,0,3); ops.fix(1,1,1)
ops.node(2,6,0)
ops.node(3,11,1)
ops.node(4,15,6); ops.fix(4,1,1)
ops.node(5,4,7)

A = 1.0 # Cross-section area
E = 3.00e6 # Actual material stiffness
K = 4.32e6 # Material stiffness for assembling stiffness matrix

ops.uniaxialMaterial('Elastic',1,E)
ops.uniaxialMaterial('Penalty',2,1,K-E,'-noStress')
matTag = 2

ops.element('Truss',1,3,5,A,matTag)
ops.element('Truss',2,1,5,A,matTag)
ops.element('Truss',3,1,2,A,matTag)
ops.element('Truss',4,2,3,A,matTag)
ops.element('Truss',5,4,5,A,matTag)
ops.element('Truss',6,3,4,A,matTag)
ops.element('Truss',7,2,4,A,matTag)
ops.element('Truss',8,2,5,A,matTag)

ops.timeSeries('Linear',1)
ops.pattern('Plain',1,1)
ops.load(5,0,-10000)

ops.algorithm('Newton','-initial')
ops.analysis('Static','-noWarnings')
ops.analyze(1)

The output of the convergence test is shown below.

The analysis takes 24 iterations to get under the default tolerance of 1e-8 on the norm of the residual force vector. Sure, the tolerance is pretty strict for such a stiff system. You see that the nodes basically stop moving after five iterations with the norm of the displacement increment vector falling below 1e-4.

As pointed out in the discussion, the inexact stiffness matrix must be at least 1/2 of the exact stiffness matrix in order for the constant stiffness iteration to converge. “One half” is a little messy for matrices, but for this example, since all members have the same elastic stiffness, the iteration requires K > E/2 for convergence.

If we make the stiffness K = E/1.99, a little larger than E/2, the iteration will converge very slowly.

And if the stiffness is a little less than E/2, i.e., K = E/2.01, the iteration will diverge.

At exactly K = E/2, the iteration will flip flop between two states, neither converging nor diverging.

Of course, if we use the correct stiffness, K = E, the iteration converges in one iteration like a linear analysis should.

If we change the underlying material from elastic to something nonlinear, we’ll see similar issues with constant stiffness iteration–slow convergence with high stiffness and potential non-convergence with low stiffness. I’ll leave that for you to experiment with.

Also check what happens when you use the KrylovNewton algorithm on the linear-elastic analyses with incorrect stiffness shown in this post.

The results shown in this post are not particular to truss models. Holding a bad stiffness constant during equilibrium iteration is a bad idea in general. However, you can run into element and constitutive models that return an incorrect (inconsistent) stiffness and lead to convergence issues.



No double meanings in this post. Just music.

Cant' Truss It