A question posted the other day in the OpenSees Facebook group asked how to add self-weight to elements. I gave the easy I-can-answer-this-in-under-two-seconds answer of “use the
It turns out the complete answer is not so simple as it depends on the type of element to which you want to apply self-weight.
The OP did not specify the types of elements, so I assumed they meant beam-column elements, for which the
'beamUniform' option is the only approach for applying self-weight. However, gentle pre-processing is required to transform the global self-weight to local uniform loads, as shown below for a plane frame element.
First, calculate the self-weight per length of the element as the density times section area. Then get the local x, y, and z axes of the element and use inner products to resolve the global self-weight onto the local directions expected by the
import openseespy.opensees as ops import numpy as np rho = 0.284*lb/inch**3 # Steel A = 20*inch**2 # Or whatever ops.element('elasticBeamColumn',1,... ,A, ...) # Or whatever b = [0,-rho*A,0] # Self-weight in global X,Y,Z ops.timeSeries('Constant',1) ops.pattern('Plain',1,1) wx = np.dot(ops.eleResponse(1,'xaxis'),b) # x'*b wy = np.dot(ops.eleResponse(1,'yaxis'),b) # y'*b wz = np.dot(ops.eleResponse(1,'zaxis'),b) # z'*b ops.eleLoad('-ele',1,'-type','-beamUniform',wy,wz,wx)
You can put these distributed load calculations in a loop over multiple elements if necessary–it’ll just take a little data management to make sure you use the correct cross-sectional areas.
Solid elements such as quads and bricks use the
'selfWeight' option for the
eleLoad command in conjunction with body forces input with the element command. The element implementations of the addLoad() method handle the self-weight calculations–no script pre-processing necessary. Because there are different issues compared to beam-column elements, I will cover solid element self-weight in another post.