OpenSees Cloud

OpenSees AMI

Insert Assertion Here

22 Apr 2026 - Michael H. Scott


Not feeling particularly motivated to write new posts, I’ve distracted myself by combing through old posts to see what could be updated and what could use an assertion here and there.

As OpenSees changes, I regularly run the scripts from blog posts to see if something breaks. Many of the scripts are sprinkled with assertions. If an assertion fails, the run fails. If I can add a new assertion to a script from an old post, great. The more assertions, the better.

Assertions don’t always have to confirm numerical results like that the tip deflection of a cantilever is \(PL^3/(3EI)\) or that reactions satisfy equilibrium. You can also test the correctness of data stored in OpenSees.

For example, in one of my pre-COVID posts, where I now barely recognize the writing as my own, I described a bug fix in how fiber sections handle torsion. The fix ensured that a fiber section created in 3D could properly aggregate torsion.

Besides taking my word for its correctness, how would you be convinced the fix actually worked? One approach is to define a fiber section with torsion in a zero legnth element, then verify the section stiffness matrix is 4x4 and that the fourth diagonal entry is in fact GJ.

import openseespy.opensees as ops
import numpy as np

E = 3000
b = 2
d = 3

GJ = 1000 # Or whatever

N = 4 # Number of section forces

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

ops.node(1,0,0,0); ops.fix(1,1,1,1,1,1,1)
ops.node(2,0,0,0); ops.fix(2,0,1,1,0,0,0)

ops.uniaxialMaterial('Elastic',1,E)

# Method 1
# ops.uniaxialMaterial('Elastic',2,GJ)
# ops.section('Fiber',1,'-torsion',2)
#
# Method 2
ops.section('Fiber',1,'-GJ',GJ)
ops.patch('rect',1,10,10,-d/2,-b/2,d/2,b/2)

ops.element('zeroLengthSection',1,1,2,1)

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

# Returns a list of section stiffness coefficients
ks = ops.eleResponse(1,'section','stiffness')
assert len(ks) == N*N

# Reshape to a matrix (useful for printing)
ks = np.array(ks).reshape((N,N))
assert ks[N-1,N-1] == GJ

The assertions pass, i.e., the section stiffness matrix is 4x4 and the last diagonal entry is GJ. Now, if for whatever reason, the implementation of torsion with fiber sections changes, my script will tell me.

While we’re at it, we can add an assertion on the section axial stiffness.

A = b*d
assert np.isclose(ks[0,0],E*A)

Note that I’m using isclose here instead of == because A is computed by the fiber section whereas GJ is straight input.

Assertions on the flexural stiffness, EI, would be difficult due to numerical integration error of fiber sections.




I work on problems related to modeling and nonlinear structural analysis. If these problems are relevant to a current professional project, feel free to reach out.