OpenSees Cloud

OpenSees AMI

A Minimal Example of Ill-Conditioning

13 Nov 2026 - Michael H. Scott


While scouring the internet for verification problems that I can solve with OpenSees, I found a rather interesting case in Example 2 from the RISA-3D verification manual.

The model is a cantilever of length L=2499 ft discretized into 2499 1 ft long elements–yes, a cantilever that is almost half a mile long. But for good reason: to explore numerical conditioning issues for a flexible model comprised of stiff individual elements.

The elastic modulus is E=100,000 ksi, the cross-section area is A=10 inch2, and the second moment of area is I=10,000 inch4. Assuming a rectangular cross-section, the width is 0.091287 inch and the depth is 109.54 inch. Eso no importa.

A load of 1 kip is applied at the free end. The closed-form free end deflection is PL3/(3EI)=8989.20 inch. For two solvers, “Standard Skyline” and “Sparse Accelerated”, RISA-3D reports a small difference in the computed free end deflection relative to the exact solution. The differences are attributed to ill-conditioning of the assembled stiffness matrix.

RISA Solver Deflection (inch) % Difference
Standard Skyline 8989.29 0.001
Sparse Accelerated 8989.28 0.001

Assuming the nodal equilibrium equations are numbered sequentially from one end of the cantilever to the other, the stiffness matrix has narrow bandwidth and low profile compared to the matrix dimension (7497 equations). Regardless of equation numbering, the stiffness matrix is very sparse.

The condition number, computed from the ratio of the largest to smallest eigenvalue of the stiffness matrix, is 3.227e15. Thus, the stiffness matrix is severely ill-conditioned. Note, however, that the condition number depends on the scaling and choice of units for the structural model.

The deflections computed with the most commonly used linear solvers in OpenSees are shown below, along with the percent differences relative to the exact solution of 8989.20 inch.

OpenSees Solver Deflection (inch) % Difference
ProfileSPD 8989.20 0.000
BandSPD 8988.90 0.003
SparseSPD 8989.18 0.000
BandGeneral 8999.86 0.119
SparseGeneral 8999.29 0.112
UmfPack 8989.51 0.003
Mumps 8963.87 0.282

The script for this analysis is shown below. Note that the Linear algorithm is used in order to match the linear analysis described in the RISA-3D verification manual. One solve and out.

import openseespy.opensees as ops

kip = 1.0
inch = 1.0
ft = 12*inch

ksi = kip/inch**2

L = 2499*ft

E = 100000*ksi
A = 10*inch**2
I = 10000*inch**4

P = 1*kip

Nele = 2499
dL = L/Nele

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

ops.geomTransf('Linear',1)

ops.node(0,0,0); ops.fix(0,1,1,1)
for i in range(1,Nele+1):
   ops.node(i,i*dL,0)
   ops.element('elasticBeamColumn',i,i-1,i,A,E,I,1)

ops.timeSeries('Constant',1)
ops.pattern('Plain',1,1)
ops.load(Nele,0,P,0)

ops.system('UmfPack') # Or other solver
ops.algorithm('Linear')
ops.analysis('Static','-noWarnings')
ops.analyze(1)

Try the analysis with Nele=21, where the cantilever is discretized into 21 elements, each of length 119 ft. You’ll see all the solvers in OpenSees give the same deflection, matching the exact solution to about 11 significant figures.

But because the model with 2499 elements is severely ill-conditioned, the results are not a verdict on the accuracy of each solver in OpenSees. If you add one more 1 ft element, making the cantilever 2500 ft long, or if you discretize the 2499 ft long cantilever into 2500 elements instead of 2499, how will the results change?

These are questions for another post.