Used for flexible supports and flexible connections, among other things, zero length elements are perhaps the most versatile modeling tools available in OpenSees.
One of the confusing things about zero length elements is how to properly define asymmetric response. For example, with a bridge abutment, you want to ensure the zero length element correctly interprets gap closing.
There are two things to remember:
- Although zero length elements have zero length, you can draw these elements as two separated nodes. Node I is the origin of the local axes and node J is a short distance away along the local x-axis–or along whichever axis you’ve defined a material.
- The deformation of zero length elements is the global displacement/rotation of node J relative to node I, i.e., , transformed to the local system by dot products with the local x, y, and z axes.
Another thing to always keep in mind for all elements, not just zero length elements, is that internal sign convention for tension and compression, or for positive and negative flexure, is different from the global sign convention for external loads and displacements.
A simple example illustrates the point. Consider a zero length element with a compression-only elastic-no-tension (ENT) material and a load intended to put the spring in compression.
import openseespy.opensees as ops ops.wipe() ops.model('basic','-ndm',2,'-ndf',3) ops.node(1,0,0); ops.fix(1,0,1,1) ops.node(2,0,0); ops.fix(2,1,1,1) ops.uniaxialMaterial('ENT',1,200.0) ops.element('zeroLength',1,1,2,'-mat',1,'-dir',1,'-orient',1,0,0,0,1,0) ops.timeSeries('Constant',1) ops.pattern('Plain',1,1) ops.load(1,5.0,0,0) ops.analysis('Static') ops.analyze(1)
Based on the x-axis given in the element definition, we have the following conceptual sketch.
All is good. For uI>0 and uJ=0, we have a negative deformation, engaging the compression only spring. The displacement of node 1 will be P/E, as expected.
Now what happens if we swap nodes 1 and 2 in the element definition, making node 1 the J node and node 2 the I node. Nothing changes with the global model. Node 1 is free, node 2 is fixed, and the load is applied at node 1 in the global X direction.
# Swap nodes 1 and 2 in element definition ops.element('zeroLength',1,2,1,'-mat',1,'-dir',1,'-orient',1,0,0,0,1,0)
With node I as the anchor and the global load applied at node 1, the spring is now in tension. We have uI=0 and uJ>0, leading to positive deformation. The analysis will fail because there is no stiffness.
Let’s go back to the original definition of node 1 as I and node 2 as J, but rotate the local x-axis 180 degrees.
# Flip local x-axis in element definition ops.element('zeroLength',1,1,2,'-mat',1,'-dir',1,'-orient',-1,0,0,0,1,0)
Although we have uI>0 and uJ=0, the global-local transformation flips the sign on the deformation, putting the spring into tension and the analysis will fail with no stiffness.
Without going into a largely repetitive explanation, know that you will run into the same issues with zero length rotational springs with asymmetric flexural response. However, I believe this is a less common case than translational response, e.g., at bridge abutments. But if you’d like to see a post about zero length elements with asymmetric rotational response, let me know.