Distributed loads on frame elements in OpenSees are defined with respect to the local element axes as opposed to global axes. This choice made the implementation easy, but it can give OpenSees users more shadow work, like bagging your own groceries or pumping your own gas.
When global distributed loads act on inclined elements, e.g., snow loads on pitched roofs, you can’t simply apply a sine and cosine to transform the loads to local axes. The correct resolution onto local member axes requires a few steps that you learned in structural analysis. But, trust me, these steps are easily forgotten.
Given a global distributed load, you first compute the resultant load based on the projected length. Then, the resultant load is resolved into local components and finally, those components are spread along the element length.
Here is OpenSees Python code to perform the above steps for 2D frame elements.
# For example, element tag 12 ndI,ndJ = ops.eleNodes(12) dXY = np.subtract(ops.nodeCoord(ndJ),ops.nodeCoord(ndI)) L = np.linalg.norm(dXY) # Change the index to 1 if global load in X-direction LX = abs(dXY) FY = wY*LX xaxis = dXY/L yaxis = [-xaxis, xaxis] # Change the index to 0 if global load in X-direction # or use dot products if you feel sporty Fx = FY*xaxis Fy = FY*yaxis wx = Fx/L wy = Fy/L
# For example, element tag 12 ndI,ndJ = ops.eleNodes(12) dXYZ = np.subtract(ops.nodeCoord(ndJ),ops.nodeCoord(ndI)) L = np.linalg.norm(dXYZ) # Change the indices to 1,2 or 0,1 if global load in X- or Z- direction LXZ = np.linalg.norm([dXYZ,dXYZ]) FY = wY*LXZ xaxis = ops.eleResponse(12,'xaxis') yaxis = ops.eleResponse(12,'yaxis') zaxis = ops.eleResponse(12,'zaxis') # Change the index to 0 or 2 if global load in X- or Z- direction # or use dot products if you feel sporty Fx = FY*xaxis Fy = FY*yaxis Fz = FY*zaxis wx = Fx/L wy = Fy/L wz = Fz/L
After you get
wz, you can apply them to an element in a load pattern using the
eleLoad command. It would also be straightforward to put these steps in a function.