Software does exactly what you tell it to do. But problems arise when you don’t know–or assume you know–what instructions you’re giving.
For example, many people like to use the 'fullGenLapack'
eigenvalue solver in OpenSees because it will compute all N eigenpairs (eigenvalue with corresponding eigenvector) for a model whereas the default eigenvalue solver will only compute up to N-1 eigenpairs.
Nmodes = 3 ;# Or whatever
# Default eigenvalue solver
ops.eigen(Nmodes)
# fullGenLapack eigenvalue solver
ops.eigen('fullGenLapack',Nmodes)
The default eigenvalue solver uses the ARPACK library while 'fullGenLapack'
uses the LAPACK dggev
subroutine, which assumes the mass and stiffness matrices are full and non-symmetric.
The non-default eigenvalue solver is OK for small OpenSees models from textbooks and blogs (e.g., here), but as Frank described in his response to GitHub issue #804, regardless of how many modes you ask for with the eigen
command, even if it’s only one mode, the 'fullGenLapack'
eigenvalue solver will compute the eigenpairs for all N modes (as stated in the dggev
documentation), making this option a killer for models with more than a few hundred DOFs.
I will demonstrate the long computation times using a 3D solid model with tetrahedral elements. A material mass density of 0.00029 gives all N degrees of freedom mass. Reducing the element mesh size is an easy way to increase the number of DOFs.
For a few mesh sizes, I compute the eigenpairs of the model with the default and 'fullGenLapack'
eigenvalue solvers. First, I ask ops.eigen()
for 10 modes, then I ask for N-1 modes. The model sizes are not large with N=585, 1200, and 2304.

Whether you ask for 10 modes or N-1 modes, the 'fullGenLapack'
option takes essentially the same amount of time whereas the default eigenvalue solver takes relatively no time (under one second for these model sizes) to compute 10 modes and does much better than 'fullGenLapack'
for N-1 modes.
For the model with N=2304, a call to ops.eigen()
with the 'fullGenLapack'
option takes over three minutes (wall time) on my half-way decent laptop. Doing some back of the envelope fitting of a cubic function to the 'fullGenLapack'
data points shown in the figure, a call to ops.eigen('fullGenLapack',...)
for this model refined to N=10,000 would take about 7.5 hours on my laptop–even if I ask for only one mode. Biting off way more than I can chew…
So, never use 'fullGenLapack'
in OpenSees.
But what should you do if you really want all N eigenpairs for something larger than a toy model, e.g., because you want to show modal damping who’s boss? You should use the default eigenvalue solver after adding a high frequency (high stiffness with low mass) SDF appendage to your model. The appendage gives you N+1 modes, then you can call the default eigenvalue solver to give you the N modes you care about. Just be sure to attach the SDF appendage to a fixed DOF so that there is no interference, or coupling, with your actual model.
Here is an explanation of the fullGenLapack
issue from a recent OpenSees Cafe. I admit, I was either unaware or had forgotten about this issue. That’s why it’s important to write things down!
Thank you very much Prof. Scott. I was totally unaware of these intricacies.. Best regards.
LikeLiked by 1 person