I long ago accepted that buckling analysis would never be implemented in OpenSees.
Although there is a getGeometricTangentStiff() method in the Element interface, only PFEM fluid elements use it. Implementing this method for frame elements, assembling the geometric stiffness, and solving the generalized eigenvalue problem would require several updates to the innards of OpenSees.
I will do my best to explain Luigi’s idea, but the gist is to use the
printA function twice to capture the material and geometric stiffness matrices of a model, then do eigenvalue analysis in your script (Python makes it easy, but you could use Tcl as well).
Define a frame model with geometric nonlinearity. Typically, a corotational mesh of geometrically linear elements, but you could also use geometrically nonlinear elements. The elements should be linear-elastic, e.g.,
forceBeamColumn with elastic sections.
First, perform a static analysis with no loads so that the stiffness matrix is assembled. Then obtain the stiffness matrix using printA. Remember to use the
FullGeneral system of equations. This gives the material stiffness of the model, i.e., .
Next, apply reference loads and perform a second static analysis. Then obtain the stiffness matrix again. This gives the material stiffness of the model minus the geometric stiffness, i.e., . As you apply larger reference loads, the geometric stiffness will increase.
Solving for the material and geometric stiffness matrices, we obtain and .
Now we can perform generalized eigenvalue analysis with and , i.e., solve where P is the eigenvalue (buckling load) and x is the eigenvector (buckled shape).
Because the analyses are static, you don’t need to use the GimmeMCK integrator to get the stiffness matrix–LoadControl with will suffice.
import numpy as np import scipy.linalg as slin # # Define your model # ops.system('FullGeneral') ops.integrator('LoadControl',0) ops.analysis('Static') ops.analyze(1) N = ops.systemSize() Kmat = ops.printA('-ret') Kmat = np.array(Kmat) Kmat.shape = (N,N) ops.timeSeries('Constant',1) # Reference loads for buckling ops.pattern('Plain',1,1) ops.load(2,0,-1.0,0) ops.load(3,0,-1.0,0) ops.analyze(1) Kgeo = ops.printA('-ret') Kgeo = np.array(Kgeo) Kgeo.shape = (N,N) Kgeo = Kmat-Kgeo # Eigenvalue solution lam, x = slin.eig(Kmat,Kgeo) # Sort the positive eigenvalues lamSort = np.sort(lam[lam>0])
Below is an example that I use in my nonlinear structural analysis course and that was shown to me when I took nonlinear structural analysis.
In a nod to reality, the columns in this frame are not slender enough for elastic buckling to precede material yielding–not by a long shot. But we’ll keep going with elastic buckling.
Assuming axial rigidity of all members, we can form the 3×3 stiffness matrix (combined material and geometric) for this frame using direct assembly with exact stability functions based on the column axial loads in each load case. The gory details of that assembly are omitted from this post.
Shown below is the determinant of that 3×3 matrix as a function of the load, P, along with the eigenvalues obtained from Luigi’s method.
The results match very well! Differences can be attributed to the inclusion of axial stiffness and the number of corotational elements per member in the OpenSees model, as well as, for the higher modes, the inherent linearization of eigenvalue problems. For Load Case 2, the determinant switches from positive to negative infinity, so you can ignore the sharp vertical line at about P=27,000 kip.
Although not shown here, you can check that the eigenvectors returned by
slin.eig match the buckled shape of the frame.
One of the nice things about this approach is you don’t have to use initial sway to trick the columns in to buckling. In addition, although I only showed one story frames in this post, there’s no reason this approach will not work for multi-story frames.
So, the solution for elastic buckling analysis has been in OpenSees all along, hiding in plain sight.
Grazie mille, Luigi Caglio, for finding it.
Update: Here is a discussion from the OpenSees Cafe on the frame buckling procedure.