OpenSees Cloud
OpenSees AMI
Positive OpenSees Contact
Original Post - 19 Oct 2025 - Michael H. Scott
Show your support at Buy Me a Coffee.
Flipping through J.C. Smith’s Structural Analysis textbook, I’m confident OpenSees can handle every problem. Same goes for any other textbook on structural analysis.
However, I totally paused on Problem 9.34 as it hinted at contact nonlinearity.

The cantilever and the simple span have flexural stiffness EI=5120 kip-ft2, something in the ballpark of W6x12 steel members, but fudged to make the math a little nicer.
I couldn’t think of how to solve this problem by hand. The brute force approach involving two analyses–gap open, then gap closed–might be the only way to go. But I suspect there’s a more clever option. If you figure the problem out, let me know.
But solving this problem in OpenSees presented its own challenges, even after realizing the hinged, rigid vertical member is unimportant for the analysis model and is just a means of load transfer from the cantilever to the simple span.
Only the 0.6 inch gap matters and there are a couple options in OpenSees to model contact between the cantilever and simple span. One option is to use a zero length element with the EPPGap material (or ENT with initial strain). I tried that option–it works. But I would like to use an actual contact element.
Several contact elements are available in OpenSees, and most of them only
work for solid-to-solid contact, not with beams or shells. However, the
zeroLengthContact element
can operate in planar models with three DOFs/node
(PR #1242)
and is suitable for beam-to-beam contact.
To use the zeroLengthContact element for this problem, we offset the
cantilever from the simple span by the specified gap distance. In the
zeroLengthContact element definition, node 4 is the constrained node
and node 2 is the retained node. The normal vector points from the
retained to the constrained node.
The contact stiffness in the normal direction is set to six orders of magnitude higher than EI/L3, a representative translational stiffness of the model. Like a penalty number, you want the normal stiffness to be large enough, but not too large.
Tangential stiffness and friction force are not
important for this analysis, so those parameters are set to zero for the
zeroLengthContact element.
import openseespy.opensees as ops
from math import isclose
kip = 1
ft = 1
inch = ft/12.0
L = 8*ft
EI = 5120*kip*ft**2
P = 9*kip
gap = 0.6*inch
ops.wipe()
ops.model('basic','-ndm',2,'-ndf',3)
ops.node(1,0,gap); ops.fix(1,1,1,1)
ops.node(2,L,gap)
ops.node(3,0,0); ops.fix(3,1,1,0)
ops.node(4,L,0)
ops.node(5,2*L,0); ops.fix(5,0,1,0)
ops.geomTransf('Linear',1)
# A = 1, E = 1, I = EI
ops.element('elasticBeamColumn',1,1,2,1,1,EI,1)
ops.element('elasticBeamColumn',2,3,4,1,1,EI,1)
ops.element('elasticBeamColumn',3,4,5,1,1,EI,1)
kn = 1e6*EI/L**3
ops.element('zeroLengthContact2D',4,4,2,kn,0,0,'-normal',0,-1)
ops.timeSeries('Constant',1)
ops.pattern('Plain',1,1)
ops.load(2,0,-P,0)
ops.analysis('Static','-noWarnings')
ops.analyze(1)
ops.reactions()
Running the analysis, you can safely ignore the warning about the length
of the zeroLengthContact element being greater than the tolerance. In
fact, I’m surprised that warning is there because the element state
determination uses the coordinates of the element nodes, along with the
displacements, to determine contact. Probably a copy-paste remnant from
the original zeroLength element implementation. Note to self: Remove
that warning message.
The following assertions verify that both reactions of the simple span are equal to 2.5 kip (the “back of the book” answer) and that the difference in deflection between the free end of the cantilever and the middle of the simple span is equal to the gap distance.
R3 = ops.nodeReaction(3,2)
R5 = ops.nodeReaction(5,2)
assert isclose(R3,2.5*kip,rel_tol=1e-5)
assert isclose(R3,R5)
u2 = ops.nodeDisp(2,2)
u4 = ops.nodeDisp(4,2)
assert isclose(u4-u2,gap,rel_tol=1e-5)
The relative tolerance on the assertions is set to 1e-5, giving
reasonable wiggle room within the six orders of magnitude used for the
normal stiffness.
Try the analysis yourself. Also, the zeroLengthContact element should
work for inclined supports a little more easily than a regular
zeroLength element with stiff elastic materials.
Positive contact!
