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.